質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
CSV

CSV(Comma-Separated Values)はコンマで区切られた明白なテキスト値のリストです。もしくは、そのフォーマットでひとつ以上のリストを含むファイルを指します。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

2回答

208閲覧

csvファイルから単語をインポートして比較し、一文字だけ異なるものをアウトプットしたい

kkkk4

総合スコア13

CSV

CSV(Comma-Separated Values)はコンマで区切られた明白なテキスト値のリストです。もしくは、そのフォーマットでひとつ以上のリストを含むファイルを指します。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

1クリップ

投稿2019/03/04 01:36

編集2019/03/04 03:45

前提・実現したいこと

Bob、Tom、Kevinなどの1万語以上の単語が含まれているcsvファイル(1列×1万超の行)があります。(各単語の長さは異なる場合があります。)これらの単語を比較して一文字だけ異なるものを全てアウトプットしたいと考えております。

入力例:
str1 [] = "dog"、str2 [] = "fog" H(str1、str2)= 1 ここで、"dog"と "fog"は1文字異なっておりますのでdogとfogをアウトプットできたらと思います。
また、str3 [] = "sport"、str4 [] = "sports", H(str3、str4)= 1 ここで、"sport"と "sports"は文字の長さが異なっておりますが、文字の長さが一文字違うと1文字異なると判定し、sportとsportsをアウトプットできたらと思います。

要件:
(1)csvファイルから一行ごとに単語を読む方法を設計する必要があります。
(2)可能であれば、Java、python、c++のいずれかの言語で求めることができたらと考えております。

試したこと

プログラミング初心者です。当初はJava8でハミング距離を使って求めようとしたのですが、そもそもハミング距離は同じ長さの単語同士の比較しか使えないことが判明しました。(csvファイルには異なる長さの単語が含まれています。)どんな方法でもよいのでcsvファイルから単語をインポートして比較し、一文字だけ異なるものをアウトプットしたいと思います。
一つの単語と残り全ての単語の比較ですとbig o notationがO(10,000 power of 10,000)になってしまい計算できなくなってしまいますので、まずは隣接する単語どうし比較できたらと思います。どうぞよろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

cateye

2019/03/04 05:28 編集

過不足も視野に入ってますか? 文字が足りないor文字が多い・・・e.g. "cat"と"cats"おなじだが1文字多いとか? 長さが同じでと言う規制があれば高速にできそうだけど・・・ 回答もらってる内に・・・遅かったw
kkkk4

2019/03/04 05:24

"cat"と"cats"おなじだが1文字多いは、一文字異なるという風に設計したいです。質問文で右のように述べました。⇒また、str3 [] = "sport"、str4 [] = "sports", H(str3、str4)= 1 ここで、"sport"と "sports"は文字の長さが異なっておりますが、文字の長さが一文字違うと1文字異なると判定し、sportとsportsをアウトプットできたらと思います。
cateye

2019/03/04 05:34 編集

だとすれば2文字多い(少ない)は2になっちゃうんですか? であればもとの文字列長±2は見なくていい? で、もとの文字列が2文字(1文字)の時は??
kkkk4

2019/03/04 05:33

はい、もとの文字列長プラマイ2はNGとの想定で進めています。
cateye

2019/03/04 05:36

いずれにしても文字列長でふるい分けて、その後文字列の比較すれば少しは効率上がりそうですね?
guest

回答2

0

投稿2019/03/04 02:17

hayataka2049

総合スコア30933

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

cateye

2019/03/04 05:24 編集

レーベンシュタインならO(1万×1万)ですね・・・どれくらい時間かかるか? 一回1msecで28時間ぐらい・・・最適化できるんかなぁ
hayataka2049

2019/03/04 05:39 編集

・長さの差が2以上あるものはハナから相手にしない これで1桁くらい減りませんか。 ・距離が2以上あるとわかった段階で切り上げ うまく実装するともう1桁くらい減りそう。 意外とゴリ押しでも実用になりそうだなという気がしていますが、はたしてどうなるか。
jimbe

2019/03/04 06:13

単純に比較で書いてみましたが, import java.util.Arrays; public class OneLetterDifference { public static void main(String[] args) { String[] words = new String[10000]; Arrays.fill(words, "AAAAAAAAAA"); long t = System.currentTimeMillis(); for(int i=0; i<words.length; i++) { for(int j=i; j<words.length; j++) { isOneLetterDifference(words[i], words[j]); } } System.out.println((System.currentTimeMillis() - t)+" [ms]"); } /** 1文字違いの時 true を返す */ static boolean isOneLetterDifference(String s1, String s2) { int diffCount = Math.abs(s1.length() - s2.length()); for(int i=0; i<Math.min(s1.length(), s2.length()) && diffCount < 2; i++) { if(s1.charAt(i) != s2.charAt(i)) diffCount ++; } return (diffCount == 1); } } 比較のみですが, 私の i5-2400S Win7-64 では 800[ms] 程でした.
hayataka2049

2019/03/04 07:03

800msは朗報ですね。ただ、Javaは詳しくないんですが、それだとwordsの要素がすべて同じStringオブジェクトへの参照になりませんか? キャッシュとへたしたら最適化が効いて、実力より速くなる気がします。
swordone

2019/03/12 06:42 編集

これだと"live"と"alive"のようなケースが弾かれそうだけど、それは想定内? あと、間に一文字(hateとhasteみたいなの)は? (3/12 ようやく間に一文字の実在単語例を発見)
jimbe

2019/03/04 08:00

あぁ, すいません. テキトウすぎました.
cateye

2019/03/04 08:05

800msならファイルからの読み込みのほうが・・・;; ・・・10倍かかっても8秒なら許容範囲? ディスクIOの待ち時間に何かできれば早くなるかも? ちなみにjimboさんのプログラムは、うちの機械(AMD1600x+Linux mint+ NetBeans:java8)で、400msぐらいです。
jimbe

2019/03/04 08:41 編集

import java.util.Arrays; public class OneLetterDifference { public static void main(String[] args) { System.out.println(isOneLetterDifference("foo", "-foo-")); //f System.out.println(isOneLetterDifference("dog", "fog")); //t System.out.println(isOneLetterDifference("dog", "dog")); //f System.out.println(isOneLetterDifference("sport", "sports")); //t System.out.println(isOneLetterDifference("live", "alive")); //t System.out.println(isOneLetterDifference("abc", "abdc")); //t String[] words = new String[10000]; Arrays.fill(words, "AAAAAAAAAA"); long t = System.currentTimeMillis(); for(int i=0; i<words.length; i++) for(int j=i; j<words.length; j++) isOneLetterDifference(words[i], words[j]); System.out.println((System.currentTimeMillis() - t)+" [ms]"); } /** 1文字違いの時 true を返す */ static boolean isOneLetterDifference(String s1, String s2) { if(Math.abs(s1.length() - s2.length()) >= 2) return false; //2文字以上長い int i1=0, i2=0, diffCount = 0; for( ; i1<s1.length() && i2<s2.length(); i1++, i2++) { if(s1.charAt(i1) != s2.charAt(i2)) { diffCount ++; if(s1.length() < s2.length()) i1--; if(s1.length() > s2.length()) i2--; } } if(i1 != s1.length() || i2 != s2.length()) diffCount ++; return (diffCount == 1); } } 6件テストで ftfttt となりまして, 10000 ループで 750 [ms] 程と少し下がりました. 下がる要因は無いと思いますので, 100[ms] 程は上下しているかと思います><
guest

0

・ファイルを1行づつ読み込み
・コンマで分割して要素に分解
・ファイルのすべての要素を取得
・2つの要素から比較検出して該当してるかどうかを出す関数を組む
・この関数を用いて、すべての要素の総当たりを行う

この手順で実現可能ですね

投稿2019/03/04 01:41

y_waiwai

総合スコア87747

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kkkk4

2019/03/04 01:44

コメントありがとうございます。流れが理解できました。コンマで分割につきまして質問がございます。当方のセルは一列のみですが、それでも分割する必要はあるでしょうか?dog という単語を d, o, gのcharacter毎に分割ということでしょうか?
y_waiwai

2019/03/04 01:48

一般的にCSVというのは、コンマ区切りフォーマットのことなのでそう書きましたが、コンマで区切られていないのであればその必要はないです 1行づつ読み込むのは「JAVA 1行読み込み」とかなんとかでぐぐると出てくると思います
kkkk4

2019/03/04 01:50

ありがとうございました!早速試してみます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問