• ベストアンサー

非共通要素を抜き出す

perlを勉強し始めたのですが、 今 非共通要素の抜き出しに苦心しています。 助けていただければうれしいです。 以下は私が試したものなのですが どうも非共通要素を抜き出せないでいます。 何故なのでしょうか? @array = (1..10); @cmp_array = (5..10); @notfound=(); foreach $array_element (@array) { foreach $cmp_array_element (@array) { if ($array_element != $cmp_array_element) { push @notfound, $array_element; } } }; よろしくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.1

@array = (1..10); @cmp_array = (5..10); @notfound=();#@array だけにある要素 #1つのやり方 @ck{@cmp_array}=(); foreach $array_element (@array) { push(@notfound, $array_element) unless exists $ck{$array_element}; } print join(",",@notfound);#結果の表示

beginperl
質問者

補足

全ての数が表示されてしまいました。

すると、全ての回答が全文表示されます。

その他の回答 (3)

  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.4

#1>全ての数が表示されてしまいました。 ウチでは、 1,2,3,4 になりますけど・

beginperl
質問者

お礼

すいません。 非共通要素を探す前に 共通要素を調べていた為かうまく表示がされなかっただけのようです。よく確かめずにコメントしてしまい、すみませんでした。 今はきちんと表示されています。ご回答 ありがとうございました。

すると、全ての回答が全文表示されます。
  • kumoz
  • ベストアンサー率64% (120/185)
回答No.3

2つめの foreach の配列名が、間違っていますよ。@array ではなく @cmp_array でしょう。 次の部分には、問題があります。 if ($array_element != $cmp_array_element) { push @notfound, $array_element; } 上のようにしてしまうと、@cmp_array の1つの要素と違うたびに $array_element を @notfound に入れてしまうことになります。非共通要素を抜き出すためには、@cmp_array のすべての要素と比較して、同じものがないときだけ @notfound に入れるようにしなければいけません。元のコードを生かして、直してみましたので参考にしてください。 OUT: foreach $array_element (@array) { foreach $cmp_array_element (@cmp_array) { next OUT if $array_element == $cmp_array_element; } push @notfound, $array_element; }

beginperl
質問者

補足

2行目はタイプミスしました。すいません。 これもうまく働きません。 共通要素がある時に保存するようになっています。 if文がどうも違っているようです。 $array_element == $cmp_array_element; を $array_element != $cmp_array_element; と直して使ってみましたが  arrayに含まれる全ての数字が表示されてしまいます。

すると、全ての回答が全文表示されます。
  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.2

まあ #1 と同じですが %ck = (); $ck{$_} = 1 for @array; $ck{$_} = 0 for @cmp_array; @notfound = grep { $ck{$_} == 1 } keys %ck; とか. delete を使うともっとシンプルかもしれない.

すると、全ての回答が全文表示されます。

関連するQ&A

  • 「Learning Perl」(第4章、問3)

    Perl初心者です。 「Learning Perl」(オライリー社、第5版)を勉強中なのですが、4章の練習問題3でつまずいています。 #!/usr/bin/perl use strict; sub total { my $sum; foreach (@_) { $sum += $_; } $sum; } sub average { if(@_ == 0) {return} my $count = @_; my $sum = total(@_); $sum/$count; } sub above_average { my $average = average(@_); my @list; foreach my $element (@_) { if($element > $average) { push @list, $element; } } @list; } my $average = average(100, 1..10); print "\$average = $average\n"; my $barney = above_average(100, 1..10); print "\$barney = $barney\n"; とやったのですが、結果が $average = 14.0909090909091 $barney = 1 となってしまいます。 ($averageの値は正しいのですが、$barneyの値が100となってほしいのに、1になってしまっています。) すみませんが、識者の方、どこが悪いのか、ご教授お願いします。

    • ベストアンサー
    • Perl
  • 要素を削除する最適な方法

    たいへん困っています。Perlでプログラムを作成しており配列要素の削除を行なおうとしています。 例えば下のようなデーターをdata.txtファイルに保存しているとしてください。 1,洋服,婦人服,子供服,男性服, 2,時計, 3,アクセサリ, 上のデーターで1行目にある子供服を削除して 1,洋服,婦人服,男性服, 2,時計, 3,アクセサリ, のようにずらしたいのです。 私がとった方法はデーターをopenで開きforeachで行をまず呼びこみます。 if(!open(DATA,"$data")){&error('ファイル読み取りエラー。'); } else{ @data=<DATA>; close(DATA); } foreach $line (@data){ chomp $line; ($no,@sub)=split(/,/,$line); if($no eq 1){ $i=-1; foreach (@sub){$i++; if($sub[$i] eq '子供服'){next;} else{push @newsub,"$sub[$i]";next; } } push @newline,"$no,@newsub\n";} else{push @newcline,"$line\n";} } これで@newlineを表示すると 1,洋服,婦人服, 男性服, 2,時計, 3,アクセサリ, のように男性の前の部分が半角空白として保存されます。 どうしてなのでしょうか?そもそもこういったやり方が間違っているのか、それとも一部だけまちがっているのかもわかりません。お手数ですがどなたか教えてください。

    • ベストアンサー
    • Perl
  • arrayである値を持った要素のみを削除するすっきりした方法。

    PHP4で,ある値を持った要素のみを削除したarrayをかえしたいのですが,たとえば,[d]と[e]をいう値をもった要素を削除したい場合, $a = array("a", "b", "c", "d", "e"); $eraseitem = array("d", "e"); $new_a = array(); foreach($a as $value); { if (!in_array($value, $erasesitem)) { $new_a[] = $value; } } とすれば,削除できますが,ほかに何かいい方法はないでしょうか。(デフォルトの関数などを使用してすっきりとできないのでしょうか。) 詳しい方,よろしくお願いします。

    • ベストアンサー
    • PHP
  • 配列を返す関数から、一つの要素だけ取り出したい。

    例えば、配列を返す関数、get_array がある時、 その配列の0番目の要素だけが欲しい時、 Perlでは、 $val = get_array[0]; (配列リファレンスを返す場合は、$val = get_array->[0]; ) みたいな感じで書けたと思いますが、 PHPでは、 $val = get_array()[0]; みたいに書けないですよね? 以下のように、二行で書かなければダメですか? $array = get_array(); $val = $array[0];

    • ベストアンサー
    • PHP
  • ハッシュ関連のスクリプトですが、

    こんにちは。以下のスクリプトですが、 -- @array = (1 .. 100); foreach $number (@array) { if ($number % 2 == 0) { $total{'2'}++; } } #result print "2で割り切れる要素数: " , $total{'2'}, "\n"; -- 実行すると、 「2で割り切れる要素数: 50」の結果が出ます。 何となく理解はしていますが、正確に何でそうなのか 分かりません。 ご指導いただけますか? よろしくお願いします。

    • ベストアンサー
    • Perl
  • 配列の要素を表示しない

    PHP初心者です、宜しくお願いいたします。 下のような配列を表示させるソースを書きましたが、要素を表示しません。 どこが間違っているのかさっぱり分かりません。誰かお助けください。 <?php $color3 = array(0 => " red ", 1 => " green ", 2 => " blue "); foreach($color3 as $key => $val) { echo "現在の添え字は ". $key . "<br/><br/>"; echo "現在の要素は ". $Val . "<br/>"; } ?> 以下のような表示になり、要素が表示されません。 現在の添え字は 0 現在の要素は 現在の添え字は 1 現在の要素は 現在の添え字は 2 現在の要素は

    • ベストアンサー
    • PHP
  • コンテナ要素の削除について

    今vectorの勉強をしているのですが、要素を削除できなくて困っています。 下記のch1とch2において、 vector<int> ch1; vector<int> ch2; ch1.push_back(10); ch1.push_back(11); ch1.push_back(12); ch1.push_back(13); ch1.push_back(14); ch1.push_back(15); ch2.push_back(13); ch2.push_back(14); ch2.push_back(15); ch1とch2が一致する要素は削除して、一致しない値を得たいのですがどうしたらいいのでしょうか? 結果としては、 ch1に、10・11・12のみが残る感じです。 よろしくお願い致します。 int ch1_size = ch1.size(); int ch2_size = ch2.size(); vector<int>:: iterator itr1; itr1=ch2.begin(); for(int a=0;a<ch1_size;a++){ for(int b=0;b<ch2_size;b++){ if(ch1[a]==ch2[b]){ itr1+b; ch1.erase(itr1); } } }

  • SimpleHTMLDOMParserについて

    PHP Simple HTML DOM Parserを最近使い始めて まだ基本的な部分しかわからず困っています。 現在ショッピングサイトのデータを自サイトに表示するために 取得を行なっているのですが ショッピングサイトのテーブルにクラス属性などがあまり無く 指定した物を取得する方法で行き詰っています。 属性などが無いので foreach ($html->find('td[align=center] a') as $element) { array_push($test, $element); } 等で取得を行い商品とタイトルと価格等は表示が行えるようになりました。 しかし、必要のないものまで含まれてしまい その部分だけを除外したいのですが、除外方法等はありませんでしょうか? イメージ的には foreach ($html->find('td[align=center] a, td[class!=jogai]') as $element) { array_push($test, $element); } このようにすればjogaiのクラス属性を除けるかと思ったのですが 違ったようでうまくいきません・・・ 結果として、tdのalign属性=centerを取得してtdにjogaiのクラス属性が付いているものは取得しない と言う結果を望んでいます。 お分かりになる方がいましたらご教示お願いいたします。

    • 締切済み
    • PHP
  • safari2でRSSの特定要素が読めない

    お世話になります。 早速ですが、safari2でRSSの特定の要素が読めません。 具体的にはgetElementByTagNameでRSSの中の要素を取得できないことがあります。 たとえば以下のRSS(抜粋)で <item rdf:about="http://foo.bar/?eid=555567"> <link>http://foo.bar/?eid=555567</link> <title>タイトルです。</title> <description>内容です。</description> <dc:subject>ブログ</dc:subject> <dc:date>2007-05-28T16:54:38+09:00</dc:date> <dc:creator>hogehoge</dc:creator> <dc:rights>hogehoge</dc:rights> </item> 以下のコードを使って function getValue(tagName, objName, num) { if (num == undefined) num = 0; var element = objName.getElementsByTagName(tagName)[num]; if (element) { try { ret = element.firstChild.nodeValue; return ret; }catch (e){ return ""; } } else { return "no-element["+tagName+"]"; } } alert(getValue("date",items[0]))とすると”2007-05-28T16:54:38+09:00”と 表示されますが、 alert(getValue("'title'",items[0]))とすると”no-element[title]”となり要 素自体を取得できません。 いろいろためしたところ、"dc:xxx"となっている要素は取得できるのですが、先 頭に"dc:"がついていない要素の取得ができないようです。 WindowsでのIE6,IE7,Opera9,FireFox2では正常に取得できることは確認していま す。 対処法などございましたらご教授いただければ幸いです。 見づらい文となってしまい、申し訳ありません。

  • C#の質問です。2つの互いに異なるLinkedListの要素の共通部分

    C#の質問です。2つの互いに異なるLinkedListの要素の共通部分を返す関数を作ったのですが不具合がおきました。以下がコードです。 using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ConsoleApplication2 { class Program { //A,Bという2つのLinkedListを受け取ったとき、A,Bの要素の共通部分を要素とした //新たなLinkedList Cを返す関数 "kyotu" private static LinkedList<int> kyotu(LinkedList<int> A, LinkedList<int> B) { LinkedList<int> C = new LinkedList<int>(); int D = A.Count(); for (int i = 0; i < D; ++i) { if (Search(A.First(), B) == 1) {C.AddLast(A.First()); A.RemoveFirst();} else {A.RemoveFirst();} } return C; } //与えられたLinkedList Aに要素iが含まれているかを判定する関数"Search" //含まれていれば1,そうでなければ0を返す。 private static int Search(int i, LinkedList<int> A) { int k = 0; foreach (int n in A) {   if (n == i) {k = 1; break;} } return k; } //与えられたLinkedList Aの要素を全部表示する関数"Display" private static void Display(LinkedList<int> A) { foreach (int n in A) {Console.Write(n + " ");} Console.WriteLine(); } //Main関数でAとBを適当に用意し、共通部分を表示させる static void Main(string[] args) { int[] a = new int[] { 0, 1, 11, 4, 7, 12, 2, 5, 8, 9 }; LinkedList<int> A = new LinkedList<int>(a); int[] b = new int[] { 23, 6, 12, 9, -1, 0, 8, 11 }; LinkedList<int> B = new LinkedList<int>(b); Display(kyotu(A, B)); Display(kyotu(A, B)); } } } 出力結果; 「0 11 12 8 9         」 ここで問題なのは、2回目に呼んだDisplay(kyotu(A, B));がまったく表示されないということです。 詳しい方いらっしゃいましたら、アドバイスよろしくお願いいたします。コードが見づらいですが、すみません。

このQ&Aのポイント
  • EPSONプリンターEW-452AでOHPフィルムの印刷に困っています。A4・写真用紙設定をしても、真ん中部分のみ印刷され、用紙が最後まで排出されず、フィルムが傷つく問題があります。
  • OHPフィルムを使った印刷中に、EPSON EW-452Aが途中で停止し、フィルムが使用不可になる事例が発生。適切な印刷方法を探しています。
  • 印刷設定に関するトラブルシューティングを求めるEPSON EW-452Aのユーザーが、OHPフィルムが傷つく問題を解決する方法を探しています。
回答を見る

専門家に質問してみよう