No.2ベストアンサー
- 回答日時:
私はソートを利用した方法を提案します。
これなら配列の数が非常に多くても効率よく処理できると思います。
1.配列は値とポインタと削除フラグの3つを対にした構造体の配列にする
2.同じ配列をもう一つ作成して内容をコピーする
3.コピーした配列のポインタは元の配列へアクセスできるようにセットする
4.コピーした配列をソートする(ペアのポインタも一緒にしてソートする)
5.ソートした配列のポインタから元の配列へアクセスして相互にアクセスできるようにポインタをセットする
つまり、同じ配列を用意して片方はソートで並び替えて、互いに対のポインタを通して配列の値を読み取れるようにします。
この下準備ができれば、次の手順で同じ番号を詰める事ができます。
1.削除フラグには配列の番号を入れておく
2.配列を最初から読み取って、ソートした方の配列の前後の値を読み取る
3.もしソートした方の配列の前後の値がどちらも違えば、その配列の値は一つだけなので、そのまま次へ
4.ソートした配列で前の値が違って、後の値が同じなら、それは最初に出てきた値なので、そのまま次へ
5.上記の2つの条件で、それ以外だったなら二回目以降の重複する値なので、削除フラグを立てる(99999など大きい値にする)
6.配列を最後まで読み取ったら、削除フラグでソートすると重複した値だけ後ろの方に移動します。
順番に詰めるよりもソートを利用する方がかなり高速になります。
ここで注意するのはソートのアルゴリズムでクイックソートだと同じ値の順番が元の順番と違う場合があるので(安定ソートでない)比較する値を操作して安定ソートにさせるか、他の安定なソートのアルゴリズムを使う必要があります。
No.5
- 回答日時:
#2 のように「ソートして隣接要素間でチェック」が簡単かつアルゴリズム的には最速.
C++ なら配列 a に対して
#include <algorithm>
stable_sort(a, a + sizeof a/sizeof a[0]);
int *last = unique(a, a + sizeof a/sizeof a[0]);
No.4
- 回答日時:
言葉で説明するのは、ソースを書くより面倒なので、ソースコードを載せます。
int elimination( int x[], int n, const int MARK ) {
// 値が MARK とは異なる要素だけを残す。
// 戻り値は、重複していない要素の数である。
int m=0;
for ( int i=0; i<n; i++ ) {
if ( x[i]!=MARK ) x[m++]=x[i];
}
return m;
}
void dupcheck( int x[], int n, const int MARK ) {
// 最後の要素から最初の要素に向かって順番に、
// それよりも前に同じ値の要素があれば、値を MARK に置き換える。
for ( int i=n-1; i>0; i-- ) {
int j=i-1;
while ((j>=0)&&(x[i]!=x[j])) j--;
if ( j>=0 ) x[i]=MARK;
}
}
int eliminateduplication( int x[], int n ) {
// MARK は、データがとり得ない値にしておく。
// 戻り値は、重複を詰めた後の要素の数である。
int MARK=-2147483648; // INT_MIN
dupcheck( x, n, MARK );
return elimination( x, n, MARK );
}
// 使用例
#include <iostream>
int main() {
int x[]={ 4,3,1,4,2,8,1,7,8,5,5 };
int n=sizeof x / sizeof( int );
int m=eliminateduplication( x, n );
for ( int i=0; i<m; i++ ) std::cout << x[i] << " ";
std::cout << std::endl;
}
データの数が100個程度以下でしたら、ソートするよりも効率は良いと思います。
No.3
- 回答日時:
ソースも言葉も同じかとも思いますが。
最初から見ていき、確定している(重複しない)要素を増やしていけば良いかと。
最初に重複している要素が見つかって以降は重複しない要素が見つかれば確定している最後の要素番号へコピーすれば良いかと。
#include <stdio.h>
int main( void )
{
int sample[] = { 3, 5, 8, 2, 8, 1, 5, 9, 11 };
int uli; /* uniq last index */
int chi; /* checked index */
int lai; /* last index */
int isUniq;
int work;
for( uli=chi=1, lai=sizeof(sample)/sizeof(int); lai>chi; chi ++ ) {
for( isUniq=1, work=0; uli>work; work++ ) {
if( sample[work] != sample[chi] ) continue;
isUniq=0;
break;
}
if( isUniq ) {
if( chi != uli ) sample[uli] = sample[chi];
++ uli;
}
}
for( work=0; uli>work; work ++ ) printf( "No.%d %d\n", work+1, sample[work] );
return 0;
}
No.1
- 回答日時:
a[0]=1
a[1]=2
a[2]=3
a[3]=2
a[4]=4
a[5]=5
とすると、a[1]とa[3]が同じ値(2)ですね。そうすると、重複値を取り除いて詰めた結果は
a[0]=1
a[1]=2
a[2]=3
a[3]=4
a[4]=5
になりますね。このとき、a[5]をどうするかは、プログラムの仕様によると思います。
さて、重複値を見つけることと、それを取り除いて後ろから前に詰める操作を
手で行なうとき、どういう風にしますか?
手で行なうプロセスをそのままソースコードに落とし込めば、完成です。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
このQ&Aを見た人はこんなQ&Aも見ています
-
好きなおでんの具材ドラフト会議しましょう
肌寒くなってきて、温かい食べ物がおいしい季節になってきましたね。 みなさんはおでんの具材でひとつ選ぶなら何にしますか? 1番好きなおでんの具材を教えてください。
-
大人になっても苦手な食べ物、ありますか?
大人になっても、我慢してもどうしても食べれないほど苦手なものってありますよね。 あなたにとっての今でもどうしても苦手なものはなんですか?
-
これ何て呼びますか Part2
あなたのお住いの地域で、これ、何て呼びますか?
-
【大喜利】【投稿~10/21(月)】買ったばかりの自転車を分解してひと言
【お題】 ・買ったばかりの自転車を分解してひと言
-
14歳の自分に衝撃の事実を告げてください
タイムマシンで14歳の自分のところに現れた未来のあなた。 衝撃的な事実を告げて自分に驚かせるとしたら何を告げますか?
-
構造体のリスト削除
C言語・C++・C#
-
<unistd.h>をVisualStudioでつかえるようにする
C言語・C++・C#
-
ファイル内のデータを1行削除する方法
C言語・C++・C#
-
-
4
整数データの配列から同じ値のデータを削除する関数
C言語・C++・C#
-
5
特定の文字列が一致する行から、文字列を抽出する方法
C言語・C++・C#
-
6
Enterキーを押されたら次の処理に移るという事をしたい。
C言語・C++・C#
-
7
配列の要素数に変数を入れたいときには
C言語・C++・C#
-
8
C言語初心者の質問失礼します。
C言語・C++・C#
-
9
INIファイルからのデータ読込みについて
C言語・C++・C#
-
10
C言語で複数列のデータを1列のみ読み込みたい
C言語・C++・C#
-
11
バッファとは何ですか
C言語・C++・C#
-
12
配列を使わずに、変数名を動的にループで回したい
C言語・C++・C#
-
13
fgets関数を使用したときの文字あふれについて
C言語・C++・C#
-
14
C言語で特定の行を抽出する方法を教えてください。
C言語・C++・C#
-
15
C言語において、 配列要素をひとつずつ前にずらすコード
C言語・C++・C#
-
16
#define _CRT_SECURE_NO_WARNINGS について
C言語・C++・C#
-
17
C言語で特定列だけを抽出して配列に格納し、出力したいです。 読み込みファイル(read.txt) 0
C言語・C++・C#
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・一回も披露したことのない豆知識
- ・これ何て呼びますか
- ・チョコミントアイス
- ・初めて自分の家と他人の家が違う、と意識した時
- ・「これはヤバかったな」という遅刻エピソード
- ・これ何て呼びますか Part2
- ・許せない心理テスト
- ・この人頭いいなと思ったエピソード
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・あなたの習慣について教えてください!!
- ・ハマっている「お菓子」を教えて!
- ・高校三年生の合唱祭で何を歌いましたか?
- ・【大喜利】【投稿~11/1】 存在しそうで存在しないモノマネ芸人の名前を教えてください
- ・好きなおでんの具材ドラフト会議しましょう
- ・餃子を食べるとき、何をつけますか?
- ・あなたの「必」の書き順を教えてください
- ・ギリギリ行けるお一人様のライン
- ・10代と話して驚いたこと
- ・家の中でのこだわりスペースはどこですか?
- ・つい集めてしまうものはなんですか?
- ・自分のセンスや笑いの好みに影響を受けた作品を教えて
- ・【お題】引っかけ問題(締め切り10月27日(日)23時)
- ・大人になっても苦手な食べ物、ありますか?
- ・14歳の自分に衝撃の事実を告げてください
- ・架空の映画のネタバレレビュー
- ・「お昼の放送」の思い出
- ・昨日見た夢を教えて下さい
- ・ちょっと先の未来クイズ第4問
- ・【大喜利】【投稿~10/21(月)】買ったばかりの自転車を分解してひと言
- ・メモのコツを教えてください!
- ・CDの保有枚数を教えてください
- ・ホテルを選ぶとき、これだけは譲れない条件TOP3は?
- ・家・車以外で、人生で一番奮発した買い物
- ・人生最悪の忘れ物
- ・【コナン30周年】嘘でしょ!?と思った○○周年を教えて【ハルヒ20周年】
- ・10秒目をつむったら…
- ・人生のプチ美学を教えてください!!
- ・あなたの習慣について教えてください!!
- ・都道府県穴埋めゲーム
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
C# DataGridView のヘッダーセ...
-
ListViewのソートについて
-
excel VBA リストビューの行...
-
Excelですべての組合せ(重複組...
-
文字列をソートする方法
-
System.IO.Directory.GetFiles...
-
C言語 配列の長さの上限
-
配列の要素数に変数を入れたい...
-
C# Listを使わずに2次元配列の...
-
C言語のプログラムについてです
-
ヒープメモリの解放について
-
C言語の2次元配列 容量が大き...
-
関数から配列を返すには?
-
define で 配列
-
配列で格納したものをmsgboxで...
-
構造体のextern方法
-
fstream型オブジェクトを関数の...
-
LPWSTRのコピー
-
小数点入りの文字列をfloat型に...
-
スタック破壊の上手な見つけ方...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
System.IO.Directory.GetFiles...
-
VB.NETでファイル名順にファイ...
-
C# DataGridView のヘッダーセ...
-
あるディレクトリ内のファイル...
-
C言語・要素除去
-
ファイル名「1.jpg ~10.jpg~...
-
Excelですべての組合せ(重複組...
-
C言語でアナグラムを求めるプロ...
-
2次元配列を複数項目でソートし...
-
C# DataTableの行をソートしてD...
-
DataGridViewソート時に先頭行...
-
n番目に大きい数を求めるアル...
-
DataGridViewの複数列を連動し...
-
VBA基本構文の作り方 2列の...
-
配列の問題
-
構造体配列の並べ替え
-
10個の整数を入力して小さい順...
-
vbでDataTableの抽出コピー
-
リスト構造のソートで悩んでま...
-
DataGridViewの昇順降順。
おすすめ情報