teratail header banner
teratail header banner
質問するログイン新規登録
C++

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

コーディング

コーディングは、実際にコードを書く工程に関する投稿。読みやすさ、効率的な実装、書き方の工夫、スタイルガイドに関する情報も含まれます。

Q&A

解決済

2回答

379閲覧

指定区間をソートする方法

mobuu

総合スコア1

C++

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

コーディング

コーディングは、実際にコードを書く工程に関する投稿。読みやすさ、効率的な実装、書き方の工夫、スタイルガイドに関する情報も含まれます。

0グッド

0クリップ

投稿2025/06/13 06:39

0

0

整数 n, l, r と、数列 a_1, ... , a_n が与えられ
数列 a の l 番目の要素から r - 1 番目の要素だけを昇順でソート。 l 番目の要素から r - 1 番目の要素以外の要素は操作する必要がありません。また、操作後の数列 a を半角スペース区切りで出力。
#include <iostream>
using namespace std;
int main(){
int n,l,r;
cin>>n>>l>>r;
int a[n];
for(int i=0;i<n;i++){
cin>> a[i];
}
for(int i=l-1;i<r-1;i++){
for(int j=l-1;j<r-1-(i-(l-1));j++){
if(a[j]>a[j+1]){
swap(a[j+1], a[j]);
}
}
}
for(int i=0;i<n;i++){
cout<<a[i];
if(i!=n-1){
cout<<" ";
}
}
cout<<endl;
return 0;
}

入力例1
6 2 6
6 5 4 3 2 1

出力例1
6 2 3 4 5 1

このコードでの出力 6 1 2 3 4 5
どこで間違えているか中々見つけられない状況です。気づける方がいましたら教えて頂きたいです。

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

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

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

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

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

TakaiY

2025/06/13 06:56

このままではコードが読みにくいので、質問を編集して、コードの部分を </>(コードの挿入)ボタンで出てくる```と```の間に入れてインデントが保存されるようにするといいですよ。
YAmaGNZ

2025/06/13 07:24

ソートする区間がどうなっているか指定する添え字を確認すればいいのではないですか?
TakaiY

2025/06/13 08:08

> なかなか見つけられない状況 デバッガでステップ実行してみるのもいいと思います。
hiroki-o

2025/06/14 03:33

ぱっと見、int a[n];はダメだろうと思いますが、g++だと通りますね。 clang++、Visual Studioだと通りません。(当たり前) 質問者さんの環境は、g++ですか?
mobuu

2025/06/15 16:37

このサイトの仕様やステップ実行のやり方などもまだ分からなかったレベルの初心者ですが、親切な回答を頂いた皆様本当に有難い限りです。
hiroki-o

2025/06/16 23:34

int a[n];は止めたほうがよいというのが、理解してもらえなかったのは残念です。 親切でない回答で申し訳ございませんでした。
guest

回答2

0

以下の3環境で確認しました。

OSコンパイラー
Windows 11Visual Studio 2022
FreeBSD 14.2g++ 15.0.1
FreeBSD 14.2clang++ 21.0.0

C++なので

  • 動的配列はstd::vector
  • ソートはstd::sort
    を使うと楽です。
#include <iostream> // 2行追加 #include <algorithm> #include <vector> using namespace std; int main(){ int n,l,r; cin>>n>>l>>r; // 変更ここから // 入力チェック if (!(n > 0 && l > 0 && r > 0 && l < r && r <= n)) { return 1; } // 配列 vector<int> a(n, 0); // 入力 for (int &e : a) { cin >> e; } // ソート sort(a.begin() + l - 1, a.begin() + r - 1); // 出力 for (const int &e : a) { cout << e; if (&e == &a.back()) { cout << endl; } else { cout << " "; } } // 変更ここまで return 0; }

投稿2025/06/14 10:56

hiroki-o

総合スコア1442

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

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

0

ベストアンサー

この質問の事例ではバブルソートであることが察せられますが、想定するアルゴリズムは明記するのが望ましいです。
意図とコードの差がどこであるかという形で調査するとやりやすいので。

まずは話を簡単にするために範囲の考え方は脇に置いて配列 5 4 3 2 に対して並べ替えをするものとします。
このとき最初の比較回数は 3 回です。

5 ←比較→ 4 ←比較→ 3 ←比較→ 2

比較回数は対象要素数より 1 少ないのです。
比較と入れ替えを一巡したら最も大きな値は右端に寄っているので次は右端を除外してもう一度同じことをするというのがバブルソートの考え方です。

つまり、二重ループの外側のループの回数はソート対象の要素の数から 1 引いた数です。


では質問として投稿されたコードを見ていきます。

外側のループ

c

1for(int i=l-1;i<r-1;i++){

に対して入力例

6 2 6 6 5 4 3 2 1

を適用すると

c

1for(int i=2-1;i<6-1;i++){

ということになり、 4 回ループします。

実際にはソート対象は 4 個なのですからそれから 1 引いた 3 回のループでなければなりません。


r-1 は数列のインデクスが 1 始まりなのを C++ の流儀である 0 始まりに合わせるための引き算であって、要素数を比較回数に調整するためには更に 1 を引く必要があるということですね。

シンプルに範囲計算のミスです。

投稿2025/06/14 12:45

SaitoAtsushi

総合スコア5740

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

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

mobuu

2025/06/15 16:35

プログラミングがほぼ初学者の自分にとって調査の仕方や質問の仕方などなど、とても分かりやすく為になる考え方だと感じたためベストアンサーとさせて頂きます。ありがとうございました。精進します!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.30%

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

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

質問する

関連した質問