最近のVC++(2022とか)で、文字列を選択した状態で、>を入力すると、選択した内容が <選択範囲> の形で囲まれてしまう。"でも同様のことが起こる。HTMLタグとかtemplate引数とかには便利かもしれないが、選択中に文字を入力したら置換してほしい。特に、時々やるのが、メンバ関数を間違ったときに書き換えようとして状況が悪化するため、この挙動に年単位で悩まされていた。
「自動サラウンドモード」を「なし」に設定する。
メンバの修正は、VC++では、ctrl+spaceでメンバの候補リストを出すことができる。
単語だけ選択→Backspace→ctrl+spaceをするのが正当な修正方法。
前回C++で実装したクイックソートで、二つの配列を同時にクイックソートする。
#include <iostream> #include <vector>
// 配列の分割を行う関数(ピボットの位置を変更しない) template<typename Container, class QElem> size_t partition(Container& arr, size_t low, size_t high) { size_t mid = low + (high - low) / 2; // 中央の要素をピボットとして選択 QElem pivot(arr, mid); // ピボットの値を取得 size_t i = low; size_t j = high; while (true) { // ピボットより小さい要素を左側に移動 while (QElem::Lesser(arr,i,pivot) ){ i++; } // ピボットより大きい要素を右側に移動 while (QElem::Greater(arr,j,pivot) ) { j--; } // 左右の走査が交差した場合に分割終了 if (i >= j) { return j; } // 交差していない場合、要素を交換 QElem::Swap(arr, i, j); i++; j--; } }
// クイックソートを行う関数 template<typename Container, class QElem> void quick_sort(Container& arr, size_t low, size_t high) { if (low < high) { size_t pi = partition<Container,QElem>(arr, low, high); if (pi > low) quick_sort<Container, QElem>(arr, low, pi);// ピボットの左側をソート quick_sort<Container, QElem>(arr, pi + 1, high);// ピボットの右側をソート } }
// 二つの配列を一つにまとめて渡すための構造体
struct Vector2Reference { std::vector<float>& value; std::vector<std::string>& label; Vector2Reference(std::vector<float>& v, std::vector<std::string>& l) : value(v), label(l) {} size_t size() const { return value.size(); } };
struct QsortElement { float value; // Pivotの値を保存するためのオブジェクト用のコンストラクタ QsortElement(const Vector2Reference& arr, size_t index) { value = arr.value[index]; } // 要素の交換関数 static void Swap(Vector2Reference& arr, size_t i, size_t j) { std::swap(arr.value[i], arr.value[j]); std::swap(arr.label[i], arr.label[j]); } // 比較関数 static bool Lesser(Vector2Reference& arr, size_t i, const QsortElement& qe) { return arr.value[i] < qe.value; } // 比較関数 static bool Greater(Vector2Reference& arr, size_t i, const QsortElement& qe) { return arr.value[i] > qe.value; } };
int main() { std::vector<float> value; std::vector<std::string> label; value.push_back(5.0f); label.push_back("e"); value.push_back(1.0f); label.push_back("a"); value.push_back(3.0f); label.push_back("c"); value.push_back(4.0f); label.push_back("d"); value.push_back(2.0f); label.push_back("b"); Vector2Reference arr2(value, label); std::cout << "ソート前の配列: " << std::endl; for (size_t i = 0; i < arr2.size(); i++) { std::cout << arr2.value[i] << " " << arr2.label[i] << std::endl; } quick_sort< Vector2Reference, QsortElement>(arr2, (size_t)0, arr2.size()-1); std::cout << "ソート後の配列: " << std::endl; for (size_t i = 0; i < arr2.size(); i++) { std::cout << arr2.value[i] << " " << arr2.label[i] << std::endl; } return 0; }
C++でクイックソートを実装する。ただし、諸事情によりピボット保存、比較演算、スワップ関数を外部で実装し、テンプレートで渡す形式にする(QElem)。
#include <iostream> #include <vector>
// 配列の分割を行う関数 template<typename Container, class QElem> size_t partition(Container& arr, size_t low, size_t high) { size_t mid = low + (high - low) / 2; // 中央の要素をピボットとして選択 QElem pivot(arr, mid); // ピボットの値を取得 size_t i = low; size_t j = high; while (true) { // ピボットより小さい要素を左側に移動 while (QElem::Lesser(arr,i,pivot) ){ i++; } // ピボットより大きい要素を右側に移動 while (QElem::Greater(arr,j,pivot) ) { j--; } // 左右の走査が交差した場合に分割終了 if (i >= j) { return j; } // 交差していない場合、要素を交換 QElem::Swap(arr, i, j); i++; j--; } }
// クイックソートを行う関数 template<typename Container, class QElem> void quick_sort(Container& arr, size_t low, size_t high) { if (low < high) { size_t pi = partition<Container,QElem>(arr, low, high); if (pi > low) quick_sort<Container, QElem>(arr, low, pi);// ピボットの左側をソート quick_sort<Container, QElem>(arr, pi + 1, high);// ピボットの右側をソート } }
struct QsortElement { float value; // Pivotの値を保存するためのオブジェクト用のコンストラクタ QsortElement(const std::vector<float>& arr, size_t index) { value = arr[index]; } // 要素の交換関数 static void Swap(std::vector<float>& arr, size_t i, size_t j) { std::swap(arr[i], arr[j]); } // 比較関数 static bool Lesser(std::vector<float>& arr, size_t i, const QsortElement& qe) { return arr[i] < qe.value; } // 比較関数 static bool Greater(std::vector<float>& arr, size_t i, const QsortElement& qe) { return arr[i] > qe.value; } };
int main() { std::vector<float> arr = {5.2f, 1.8f, 3.2f, 4.3f, 2.7f}; std::cout << "ソート前の配列: " << std::endl; for (size_t i = 0; i < arr.size(); i++) { std::cout << arr[i] << " " << std::endl; } quick_sort< std::vector<float>, QsortElement>(arr, (size_t)0, arr.size()-1); std::cout << "ソート後の配列: " << std::endl; for (size_t i = 0; i < arr.size(); i++) { std::cout << arr[i] << " " << std::endl; } return 0; }
WSL2内でvimを使っているのだがコメントが濃い青で背景が黒で極めて見づらいので色を変えたい。
~/.vimrc ファイルがなければ新規作成し、以下の設定を書き込めば、コメントの色は変わる。
これでいいと思ったのだが、自動でタブがインデントされなかったり、コメント行で改行しても次の行頭にコメントが入らなかったりと、なぜか設定が変わる。
以下のように設定することで既存の設定を維持してコメント色を変更できる。
" 既存の設定を保持するための設定 syntax enable filetype plugin indent on " コメントの色を緑色に変更 highlight Comment ctermfg=Green guifg=Green " 自動インデントを有効にする set autoindent set smartindent " コメントの継続を有効にする set formatoptions+=cro
vtkAssemblyで、二つ以上のvtkActorを纏めることができる。
#include <iostream> //VTK_MODULE_INITに必要 #include <vtkAutoInit.h> #include <vtkSmartPointer.h> #include <vtkRenderer.h> #include <vtkRenderWindow.h> #include <vtkRenderWindowInteractor.h> //円筒とその表示に必要 #include <vtkCylinderSource.h> #include <vtkPolyDataMapper.h> #include <vtkActor.h> #include <vtkCubeSource.h> #include <vtkProperty.h> #include <vtkAssembly.h> #include <vtkTransform.h> #pragma comment(lib,"opengl32.lib") #pragma comment(lib,"psapi.lib") #pragma comment(lib,"dbghelp.lib") #pragma comment(lib,"ws2_32.lib") // コールバック関数を使用するのに必要 #include <vtkCallbackCommand.h> //必須 VTK_MODULE_INIT(vtkRenderingOpenGL2); VTK_MODULE_INIT(vtkInteractionStyle); /////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////
// コールバック関数に渡すデータ struct MyData { vtkSmartPointer<vtkAssembly> assembly; }; // タイマーのコールバック関数 void MyTimerCallbackFunction(vtkObject* caller, long unsigned int eventId, void* clientData, void* callData) { MyData* data = static_cast<MyData*>(clientData); static int angle = 0; vtkSmartPointer<vtkTransform> tra = vtkSmartPointer<vtkTransform>::New(); tra->RotateWXYZ(angle+=10, 0, 0, 1); tra->Update(); data->assembly->SetUserTransform(tra); // 画面更新 auto interactor = static_cast<vtkRenderWindowInteractor*>(caller); interactor->Render(); }
/////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////// vtkSmartPointer<vtkActor> createActor1(); vtkSmartPointer<vtkActor> createActor2(); int main(int /*argc*/, char** /*argv*/) { // アクタを作成 vtkSmartPointer<vtkActor> actor1 = createActor1(); vtkSmartPointer<vtkActor> actor2 = createActor2(); // アクタをまとめてアセンブリを作成 vtkSmartPointer<vtkAssembly> assembly = vtkSmartPointer<vtkAssembly>::New(); assembly->AddPart(actor1); assembly->AddPart(actor2); ////////////////////////////////////// auto renderer = vtkSmartPointer<vtkRenderer>::New(); renderer->ResetCamera(); // アセンブリをレンダラに追加 renderer->AddActor(assembly); ////////////////////////////////////// auto interactor = vtkSmartPointer<vtkRenderWindowInteractor>::New(); auto renderWindow = vtkSmartPointer<vtkRenderWindow>::New(); renderWindow->AddRenderer(renderer); renderWindow->SetInteractor(interactor); renderWindow->Render(); ////////////////////////////////////// ////////////////////////////////////// // タイマーに渡す構造体の作成 MyData callbackData{ assembly }; // タイマー作成 auto timerCallback = vtkSmartPointer<vtkCallbackCommand>::New(); timerCallback->SetCallback(MyTimerCallbackFunction); // コールバック関数を設定 timerCallback->SetClientData(&callbackData); // コールバック関数に渡すデータを設定 interactor->AddObserver(vtkCommand::TimerEvent, timerCallback); // タイマーイベントにコールバック関数を設定 interactor->Initialize(); interactor->CreateRepeatingTimer(100); // 100msごとにタイマーイベントを発生させる ////////////////////////////////////// ////////////////////////////////////// interactor->Start(); //イベントループへ入る return 0; }
vtkSmartPointer<vtkActor> createActor1() { // 1つ目の立方体を作成 vtkSmartPointer<vtkCubeSource> cubeSource1 = vtkSmartPointer<vtkCubeSource>::New(); vtkSmartPointer<vtkPolyDataMapper> mapper1 = vtkSmartPointer<vtkPolyDataMapper>::New(); mapper1->SetInputConnection(cubeSource1->GetOutputPort()); vtkSmartPointer<vtkActor> actor1 = vtkSmartPointer<vtkActor>::New(); actor1->SetMapper(mapper1); actor1->GetProperty()->SetColor(1, 0, 0); // 赤色 return actor1; } vtkSmartPointer<vtkActor> createActor2() { // 2つ目の立方体を作成 vtkSmartPointer<vtkCubeSource> cubeSource2 = vtkSmartPointer<vtkCubeSource>::New(); cubeSource2->SetCenter(1.2, 0, 0); // 位置を変更 vtkSmartPointer<vtkPolyDataMapper> mapper2 = vtkSmartPointer<vtkPolyDataMapper>::New(); mapper2->SetInputConnection(cubeSource2->GetOutputPort()); vtkSmartPointer<vtkActor> actor2 = vtkSmartPointer<vtkActor>::New(); actor2->SetMapper(mapper2); actor2->GetProperty()->SetColor(0, 1, 0); // 緑色 return actor2; }
二つのオブジェクトにまとめて行列を適用している。