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

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

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

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

Q&A

解決済

4回答

3188閲覧

Javaで、条件に合致する文字列を並べ替える

dwayne03

総合スコア7

Java

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

0グッド

0クリップ

投稿2016/07/24 22:56

Javaで、Mapに格納された以下の例のような文字列
(例)
キー データ(文字列)
1 /a/b/c/d/e
2 /a/b/c/d/f
3 /a/b/c//e (""はワイルドカード)
4 /a/b/c/d
5 /a/b/c

を、"/"の数が多い順番で並び替えようと考えています。
ある特定の文字を含んだ文字列を、特定の文字が登場する回数が多い順に並べ替えるための考え方を教えていただけないでしょうか。

ちなみに、String型のsplitメソッドを用いようと考えていたのですが、自分だけでは解決しませんでした。よろしくお願い致します。

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

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

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

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

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

matobaa

2016/07/24 23:11

並び替えた結果はどうなるのが正解か、質問に追記していただけませんか。
dwayne03

2016/07/24 23:29

ご指摘ありがとうございます。 ソートした際は例と同じ順番になるのが正解となります。
matobaa

2016/07/25 01:17

/a/b/c/d/e と /a/b/c/d/f はともに"/"が5個なので、条件がこれだけだと順不同になってしまいますがよいでしょうか? それとも必ずこの順序になる必要がありますか? そのときは2番目のキーはなんでしょうか?
dwayne03

2016/07/25 01:31

/ の数が同じ文字列は順不同で大丈夫です。
guest

回答4

0

ベストアンサー

まずこんな感じのComparatorを作ります(匿名クラスでもいい)。

java

1class SlashComparator implements Comparator<String> { 2 3 @Override 4 public int compare(String o1, String o2) { 5 // 通常Comparatorは昇順(小さい方から順に並べる)に並べるようにするため、 6 // 降順に並べるためには、このように引数の順番を逆にする 7 return Integer.compare(o2.split("/").length, o1.split("/").length); 8 } 9}

このコンパレータに従うようなTreeMapを作成し、元のMapをまるごと突っ込めば完成です。

java

1Map<String, Integer> map = new TreeMap<>(new SlashComparator()); 2map.putAll(originalMap);

単純に「並べ替えたあとのキーのリストがほしい」というのであれば、keySet()からリストを作成してこのComparatorを使ってソートすればOKです。

java

1List<String> list = new ArrayList<>(); 2list.addAll(originalMap.keySet()); 3Collections.sort(list, new SlashComparator());

投稿2016/07/25 02:50

swordone

総合スコア20651

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

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

0

考え方:
Object Ordering
https://docs.oracle.com/javase/tutorial/collections/interfaces/order.html

数え方:
Java: How do I count the number of occurrences of a char in a String?
http://stackoverflow.com/a/35242882/2262143

投稿2016/07/25 01:52

matobaa

総合スコア2493

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

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

0

Java

1Map<Integer, String> map = new HashMap<>(); 2map.put(1, "/a"); 3map.put(2, "/a/b"); 4map.put(3, "/a/b/c"); 5map.put(4, "/a/b/c/d"); 6map.put(5, "/a/b/c/d/e"); 7 8Comparator<String> comparator = (v1, v2) -> { 9 Pattern pattern = Pattern.compile("/"); 10 Matcher matcher1 = pattern.matcher(v1); 11 int count1 = 0; 12 while (matcher1.find()) { 13 count1++; 14 } 15 16 Matcher matcher2 = pattern.matcher(v2); 17 int count2 = 0; 18 while (matcher2.find()) { 19 count2++; 20 } 21 22 return Integer.compare(count1, count2); 23}; 24 25Object[] values = map.values().stream().sorted(comparator.reversed()).toArray(); 26LinkedHashMap<Integer, String> result = new LinkedHashMap<>(); 27for (int i = 0; i < values.length; i++) { 28 result.put(i + 1, Objects.toString(values[i])); 29} 30 31result.entrySet().stream().forEach(e -> System.out.println(String.format("%d:%s", e.getKey(), e.getValue()))); 32 33/* 34 * 1:/a/b/c/d/e 35 * 2:/a/b/c/d 36 * 3:/a/b/c 37 * 4:/a/b 38 * 5:/a 39 */

投稿2016/07/25 01:08

root_jp

総合スコア4666

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

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

0

Mapインタフェースの実装で順序を持てるのは次のものです。

LinkedHashMap:キーを格納した順 TreeMap:キーの昇順

文字の出現回数を数える方法

int split(String str, char target){ return str.split(target + "").length - 1; } ※split()の引数は正規表現として扱われるのでメタキャラを利用する場合は注意してください

以上を踏まえて、次の処理で実装できませんか?

1.Mapに格納されたデータを全てループで回し、文字の出現回数をそれぞれのキーに結びつける。
2.文字の出現回数順にソート
3.LinkedHashMapに格納

投稿2016/07/24 23:51

moonphase

総合スコア6621

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問