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

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

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

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

C++

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

Q&A

解決済

1回答

1416閲覧

Java MatcherとStreamの使い方について(C++で使われるfind()やend()をJavaで表現したい)

kagome96

総合スコア11

Java

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

C++

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

0グッド

0クリップ

投稿2020/04/28 12:46

編集2020/04/29 14:40

こちらのサイトの問題をjava8で解いています。
https://www.hackerrank.com/challenges/absolute-permutation/problem
(問題内容)
・整数 n(1≦n≦10)と整数 k(0≦k<n)が入力される。
・1からnまでの順列(n = 5だったら1,2,3,4,5)の数字を全て使って
順列の位置i(1〜n)との絶対値の差が常にkになるような配列をつくって戻り値として返す。
・該当しなかったら-1のみ配列に入れて戻り値として返す。
→上記の処理を書いた「absolutePermutation()」を完成させる。

苦戦したため、知人にC++で回答を作ってもらいました。
C++の回答をJavaに変えて書きたいのですが、わからない点があるため、質問させてください。

C++

1//知人に書いてもらったコード 2コード 3vector<int> absolutePermutation(int n, int k) { 4 set<int> used; 5 bool flag = true; 6 vector<int> ans; 7 for(int i=1; i<=n; i++) { 8 if(i-k >= 1 && used.find(i-k) == used.end()) { 9 used.insert(i-k); 10 ans.push_back(i-k); 11 continue; 12 } 13 if (i+k <= n && used.find(i+k) == used.end()) { 14 used.insert(i+k); 15 ans.push_back(i+k); 16 continue; 17 } 18 flag = false; 19 break; 20 } 21 22 if(!flag) { 23 return vector<int>(1, -1); 24 } else { 25 return ans; 26 } 27}

わからない点
■if(i-k >= 1 && used.find(i-k) == used.end())の部分

→find()やend()を使用する場合、Matcherを使うことになると思いますが、
調べてみると、「Stringの文字列からある文字列を検索する方法」しか見つけられず、
Set型からある数字を見つけ出す方法がわかりません。

 →Matcherを使わず、used.stream()で検索をかける方法を試そうと思いましたが、
end()をどのように表現するかがわかりません。
また、いちいちListを用意しようとしているのですが、何かいいやり方はあるのでしょうか。

■戻す値がint[]なので、最初からansをint[]で書きたいのですが
定義する際に長さを指定できないため、Listを使っています。
if(!flag)以下でint[]に変換していますが、この方法でよいのでしょうか。
なにかいい方法があれば教えていただけると助かります。

途中までJavaで書いたコード(Streamを使っている方)

Java

1static int[] absolutePermutation(int n, int k) { 2 Set<Integer> used = new HashSet<Integer>(); 3 boolean flag = true; 4 ArrayList<Integer> ans = new ArrayList<>(); 5 6 for(int i=1; i<=n; i++) { 7 if(i-k >= 1){ 8 List<Integer> a = used.stream().filter(x -> x==(i-k)).collect(toList()); 9 if( a == ■ここでused.end()の表現をしたい){ 10 used.add(i-k); 11 ans.add(i-k); 12 continue; 13 } 14 } 15 if(i+k <= n){ 16 List<Integer> a = used.stream().filter(x -> x==(i+k)).collect(toList()); 17 if( a == ■ここでused.end()の表現をしたい){ 18 used.add(i+k); 19 ans.add(i+k); 20 continue; 21 } 22 } 23 flag = false; 24 break; 25 } 26 if(!flag) { 27 ans.add(-1); 28 int[] a = new int[ans.size()]; 29 a[0] = ans.get(0); 30 return a; 31 } else { 32 int[] a = new int[ans.size()]; 33 for(int i = 0;i < ans.size();i++){a[i] = ans.get(i);} 34 return a; 35 } 36}

拙い文で申し訳ありません。
ヘルプしていただけると助かります。
よろしくお願いします。

ーーーーーーーーーーーーーーーーーーーーーーーー
修正したコードを掲載します。
コンパイルはできましたが、テストが模範どおりの結果になりません。

修正点をご指摘いただけると助かります。

Java

1 Set<Integer> used = new HashSet<Integer>(); 2 boolean flag = true; 3 int[] ans = new int[n]; 4 5 for(int i=1; i<=n; i++) { 6 if ( i-k >= 1 && !used.contains(i-k) ){ 7 used.add(i-k); 8 ans[n-1]= i-k; 9 continue; 10 } 11 if( i+k <= n && !used.contains(i+k) ){ 12 used.add(i+k); 13 ans[n-1]= i+k; 14 continue; 15 } 16 flag = false; 17 break; 18 } 19 20 if(!flag) { 21 ans[0] = -1; 22 return ans; 23 } else { 24 return ans; 25 } 26 } 27コード

結果

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

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

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

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

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

guest

回答1

0

ベストアンサー

if(i-k >= 1 && used.find(i-k) == used.end())

if ( i-k >= 1 && !used.contains(i-k) )

戻す値がint[]なので、最初からansをint[]で書きたい

return ans.toArray()

[追記] バグみっけ。

Java

1import java.util.*; 2 3public class Trial { 4 5 static int[] absolutePermutation(int n, int k) { 6 Set<Integer> used = new HashSet<Integer>(); 7 boolean flag = true; 8 int[] ans = new int[n]; 9 10 for(int i=1; i<=n; i++) { 11 if ( i-k >= 1 && !used.contains(i-k) ){ 12 used.add(i-k); 13 ans[i-1]= i-k; // ココと 14 continue; 15 } 16 if( i+k <= n && !used.contains(i+k) ){ 17 used.add(i+k); 18 ans[i-1]= i+k; // ココ 19 continue; 20 } 21 flag = false; 22 break; 23 } 24 25 return flag ? ans : new int[]{-1}; 26 } 27 28 public static void main(String[] args) { 29 for ( int item : absolutePermutation(2, 1) ) { 30 System.out.printf("%d ", item); 31 } 32 System.out.println(); 33 for ( int item : absolutePermutation(3, 0) ) { 34 System.out.printf("%d ", item); 35 } 36 System.out.println(); 37 for ( int item : absolutePermutation(3, 2) ) { 38 System.out.printf("%d ", item); 39 } 40 System.out.println(); 41 } 42}

投稿2020/04/28 15:56

編集2020/04/30 07:03
episteme

総合スコア16612

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

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

kagome96

2020/04/29 13:36

ご回答、ありがとうございます。 return ans.toArray()に変更したところ、 Object[] cannot be converted to int[]、というエラーが出てきてしまいました。 やはり、ArrayList<Integer>からarrayに変換するのはFor文を使わないといけないのでしょうか。。
swordone

2020/04/29 14:13

そもそも「(配列を)定義する際に長さを決定できない」と言っていますが、 長さはnか1のはずです。 基本nにしておいて、不適の時に{-1}を返すようにすればそれですみます。
kagome96

2020/04/29 14:35

ありがとうございます。 nを指定して書くと、 出力したときに、-1の後に、残りの長さ分「0」が出てきてしまいます。 削除ができればいいのですが・・
swordone

2020/04/29 14:51

いや、だからね? その時だけ return new int[]{-1}; ってすればいいじゃない?
kagome96

2020/04/29 15:07

なるほど、今理解しました。 ありがとうございます。 -1 は正しく出力できました。m(_ _)m -1以外のところがうまく出力できず、 原因をご指摘いただけると助かります・・・。
kagome96

2020/04/30 06:28

ありがとうございます。 ans[i-1]= i-k; ans[i-1]= i+k; に原因があるということですね。 「push_back()」にこれにあたるものを使う必要があるということでしょうか? よくわかっておらず、何度もすみません。
episteme

2020/04/30 06:38

ぃゃぃゃ、あなたのコードでは ans[n-1] になってたから直した。
kagome96

2020/04/30 06:56

すみません。気づきませんでした。 直したところちゃんと動きました。 ありがとうございましたm(_ _)m
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問