この記事で扱っていること
キューの中の特定の要素を削除する方法
を紹介しています。
注意:すべてのエラーを確認しているわけではないので、記事の内容を実装する際には自己責任でお願いします。また、エラー配線は適当な部分があるので適宜修正してください。
並列処理を得意とする(実装するのが容易な)LabVIEWにとって、ループ間でデータを受け渡しするための仕組みの一つであるキューはとても出番の多い機能です。
データの先入れ先出しという、順番を守ってデータを処理してくれるのが大きな特徴で、基本的にこの先入れ先出しという仕組みは便利なのですが、たまに「途中の要素を変更したい、なかったことにしたい」という場面があります。
いわばキャンセル操作にあたりますが、キューの関数自体にはそのような途中の要素を削除するものはないため、使える関数を駆使してこの仕組みを用意する必要があります。
本記事では、キューの中にある要素のうち特定の要素を削除する方法を紹介しています。
どんな結果になるか
概念を簡単に説明するために、数値を扱うキューで説明していきます。
フロントパネルには、キューに入れたい要素、デキューされた要素、そして削除したい要素を指定するための制御器や表示器、そしてブールボタンがあります。
キューに入れたい要素を指定して対応するブールボタンを押すとそれがキューにたまっていきます。
デキューボタンを押せば、キューに入れた順番に表示されますが、途中の要素を指定して削除するボタンを押すとその要素はキューから消えるようになります。
もう少し複雑にして、クラスタでも同じようなことができます。
例えば以下の図では、文字列と数値を含んだクラスタをキューの要素としています。
削除対象としたい文字列の値を入力すれば、その値の文字列を含んだクラスタをキューの途中であっても削除することができます。
プログラムの構造
実際のアプリケーションでの実装は並列ループ間でデータをやり取りすることと思いますが、今回は方法を紹介することに焦点をあて、一つのループでエンキュー、デキューするようにしています。
なので、以下の図では、本来はあまり実装しないであろう、一つのループにそれぞれの機能を盛り込んだ形としていますが、実際にこの考え方を用いる場合には異なるループ間で行うようにしてください。
エンキュー、デキューは通常のキューを取り扱うプログラムと同じ考え方なので特に説明することはありませんが、問題は要素を削除する仕組みです。
とはいってもやっていることは簡単で、キューステータス取得の関数でキューの中にある全要素にアクセスし、1D配列検索で指定の要素を見つけてその要素を配列から削除し、改めて「残り」の要素をキューに入れなおしています。
入れなおす前には一度キューの要素を全て削除(キューから排除)する必要があることに注意してください。
データタイプが変わっても考え方は同じです。
クラスタの場合、クラスタの要素の中の一部(今回は文字列)に対して削除したい要素の値を指定するので、その対象となる要素だけの配列をまず用意してから、あとは先ほどと同じような処理を行います。
複数の要素を削除する場合
上で紹介した例は、削除したい要素をキューの中で1つだけ削除していました。
そうではなく、同じ要素が複数ある場合にそのすべてを削除する場合には、まず削除したい要素がキューのどこに存在するのか、要素の番号を全て調べる必要があります。
1D配列検索の関数で開始指標を決められることから、要素を一つ見つけたら、その要素の次から再び検索をかけるように処理します。
複数の削除対象要素の要素番号が得られたら配列から削除していくのですが、一度に複数の配列要素を削除する関数はないので、一つずつ削除していきます。
このとき、削除を行う大元の配列から1つ要素を削除したら、それ以降の要素番号は1つずつずれることになるため、検索して得られた複数の要素番号も順にずらす必要があります。
本記事ではキューの中の特定の要素を削除する方法を紹介しました。
通常は処理の順番を一定に保つために先入れ先出しの原則を守ることが多いと思いますが、緊急時に特定の処理を省いたり、あとからキャンセル操作のような形で処理の流れを変えるときに参考になればうれしいです。
ここまで読んでいただきありがとうございました。
コメント