iT邦幫忙

0

檢查陣列內的數字是否重複

eit 2019-12-19 19:41:542629 瀏覽

要檢查陣列內的數字是否有重複,如果有的話是誰重複了,重複了幾次

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

/* run this program using the console pauser or add your own getch, system("pause") or input loop */

int main(void)
{
int n,number[1000],i,a;
srand(time(NULL));
replay:
printf("請問需要幾個亂數(需小於1000個):");
scanf("%d",&n);
if(n>1000)
{
printf("輸入的數不可大於1000\n");
goto replay;
}
else
{
for(i=0;i<n;i++)
{
number[i]=(rand()%100)+1;
}
}
printf("排序前:");
for(a=0;a<i;a++)
{
printf("%d ",number[a]);
}
printf("\n");
int k=0,j=0;
int temp=0;
for(k=0;k<n;k++)
{
for(j=k;j<n;j++)
{
if(number[j]<number[k])
{
temp=number[j];
number[j]=number[k];
number[k]=temp;
}
}
}
printf("排序後:");
for(j=0;j<n;j++)
{
printf("%d ",number[j]);
}
/-----------------------------------------------------------------以下是我自己打的程式,但有問題,求解/
int l=0,x=0,y=0,re[1001];
for(x=0;x<n;x++)
{
if(number[x]==number[x+1])
{
y+=1;
for(x=x;number[x]==number[x+1];x++)
{
l+=1;
}

re[y]=l;
re[y+1]=number[x];
}
}
for(y=1;y<1001;y+=2)
{
if(re[y]!=0)
{
printf("\n%d重複了%d次",re[y+1],re[y]);
}
}

system("pause");
return 0;
}

ccutmis iT邦高手 4 級 ‧ 2019-12-19 20:01:08 檢舉
這是學校作業嗎?
小魚 iT邦大師 1 級 ‧ 2019-12-19 20:04:00 檢舉
出現goto了.

2 個回答

2
小魚
iT邦大師 1 級 ‧ 2019-12-19 20:01:58
最佳解答

這是學校作業嗎?
現在應該很少在用純C的了,
實務上會用到的都是高手了.

p.s.稍微測了一下

if (number[x] == number[x + 1])
		{
			y += 1;

這邊y不要先加,
應該處理完再加,
然後以你的邏輯應該一次要加2.

然後你的l沒有歸零的動作,
會越來越多.

for (y = 1; y < 1001; y += 2)

這一行有問題,
你根本沒那麼多資料啊,
只要執行實際有的資料即可.
(也就是從 0 到 < y)

if (re[y] != 0)

你加了這行出發點不錯,
知道要判斷,
但是很可惜 C/C++的int預設值不是0,
而是非常奇怪的負值,
所以你的判斷等於沒有判斷.
除非你有先做初始化,
譬如這樣

int num[1000];
for(int i=0;i<1000;i++)
    num[i] = 0;

陣列初始化其實有更簡單的解法,不過要視編譯器的支援程度
另外C/C++的預設值其實就是記憶體裡既有的值,不見得會是什麼數字,2,147,483,647~-2,147,483,648都有可能

小魚 iT邦大師 1 級 ‧ 2019-12-21 08:14:53 檢舉

因為他的語法看起來是傳統的C語言,
還是用最原始的方式比較保險.

1
打狗松鼠
iT邦新手 4 級 ‧ 2019-12-20 09:40:01

先談談思路:
一個陣列裡怎麼檢查數字有無重複?
直覺上來說,便是掃一次陣列,看有沒有數字出現超過1次
但怎麼做到更快的作法?

舉例:
(不考慮輸出入等其他要素,單純演示最關鍵的演算法)
(虛擬碼,實際作法因各語言有所不同,後面會提示C/C++你可以怎麼做)

宣告並初始化陣列-

int ary[] = {0};

窮舉尋找重複的值-
1.

bool isRepeat = false; //是否重複
for (int i = 0;i < ary.length;i++)
{
    for (int j = 0;j < ary.length;j++)
    {
        if (i == j) //如果i = j,跳過
            continue;
        else if (ary[i] == ary[j])
        {
            //如果陣列索引「i」元素 = 陣列索引「j」元素 ->陣列有重複值
            isRepeat = true;
            break;
        }
        else
            continue;
    }
}

很冗長對吧?
還有更好的解法存在,但這留給你自己想

再談談語言特性:
樓主使用的是C/C++,陣列的宣告有所不同,對陣列的操作也較為特殊

陣列的初始化部分-
需注意C99以前不可使用

int ary[] = {0};

只能使用

int ary[];
int i = 0; //C99才可在迴圈內宣告變數
for (i = 0;i < ary.length;i++) //實際取陣列長度不是這樣取,一樣留給你自己找
    ary[i] = 0;

C/C++對於變數的初始化尤其重要,若沒有初始化,C/C++便會直接分配一個記憶體空間,留下該記憶體空間的原始值

另外你也可以使用指標,但這建議等你弄懂陣列後再去碰。

最後,除了組合語言因操作特性等原因,所有語言都不建議使用GOTO,那只會帶來流程混亂及開發困難、維護不易等問題。

我要發表回答

立即登入回答