輸入:int arr[] = {10, 20, 20, 30, 40, 40, 40, 50, 50}
輸出:10, 30
我的代碼:
int removeDup(int arr[], int n)
{
int temp;
bool dupFound = false;
for(int i=0;i<n;i ){
for(int j=i 1;j<n;j ){
if(arr[i] == arr[j]){
if(!dupFound){
temp = arr[i];
dupFound = true;
}
else{
arr[i] = temp;
}
}
}
}
//shift here
}
首先,我不知道這是否是最有效的方法。
我試圖找到第一個重復元素,將其分配給每個重復元素并將它們移動到陣列的末尾,這不起作用,因為無法比較最后一個重復元素。
我需要一些幫助來查找最后一個重復元素,以便我可以分配temp給它。
uj5u.com熱心網友回復:
我不明白你的代碼的邏輯。當您找到第二個arr[j]等于arr[i]您將分配temp給的元素時arr[i]。但是,當您找到第一個重復項時temp已分配。arr[i]基本上你做arr[i] = arr[i]。目前尚不清楚這應該如何找到獨特的元素。
您可以使用地圖來計算元素的頻率,然后列印頻率為 1 的元素:
#include <unordered_map>
#include <iostream>
int main()
{
std::unordered_map<int,size_t> freq;
int arr[] = {10, 20, 20, 30, 40, 40, 40, 50, 50};
// count frequencies
for (auto e : arr) { freq[e]; }
// print the elements e where freq[e] == 1
for (const auto& f : freq) {
if (f.second == 1) {
std::cout << f.first << "\n";
}
}
}
只需進行少量修改即可將唯一元素添加到向量中。
uj5u.com熱心網友回復:
與其試圖一次做所有事情,讓我們首先關注正確性:
int removeDup(int* arr, int n) {
// Note: No i ! This depends on whether we find a duplicate.
for (int i = 0; i < n;) {
int v = arr[i];
bool dupFound = false;
for (int j = i 1; j < n; j ) {
if (v == arr[j]) {
dupFound = true;
break;
}
}
if (!dupFound) {
i ;
continue;
}
// Copy values to the sub-array starting at position i,
// skipping all values equal to v.
int write = i, skipped = 0;
for (int j = i; j < n; j ) {
if (arr[j] != v) {
arr[write] = arr[j];
write ;
} else {
skipped ;
}
}
// The previous loop duplicated some non-v elements.
// We decrease n to make sure these duplicates are not
// considered in the output
n -= skipped;
}
return n;
}
uj5u.com熱心網友回復:
讓我們從物流開始(可以這么說)。陣列始終包含固定數量的專案。根本沒有辦法從 5 個專案的陣列開始,然后將其變成 2 個專案的陣列。根本做不到。
因此,作為起點,您需要回傳類似 an 之類的東西std::vector來跟蹤其大小及其包含的資料,否則您將需要跟蹤大小,并回傳一些東西來指示其中有多少元素該陣列在處理后有效。
可能最簡單的方法是使用類似 anstd::unoredered_map來計算專案,然后遍歷地圖,并在(且僅當)其計數為 1 時在輸出中插入一個專案。
std::unordered_map<int, std::size_t> counts;
for (int i=0;i<n; i )
counts[arr[i]];
std::vector<int> output;
for (auto item : counts)
if (item.second == 1)
output.push_back(item.first);
return output;
如果您想就地修改資料,我將從對輸入資料進行排序開始。然后,您將從兩個索引開始:一個用于“輸入”位置,一個用于“輸出”位置。output從零開始,input從 1 開始。
總體思路很簡單:我們看看data[input]它是否與前面和后面的元素都不同。如果是這樣,我們將其復制到data[output],并增加輸出位置。
由于這試圖同時查看前面和后面的元素,因此我們必須包括陣列開頭和結尾的特殊情況。如果第一個元素與后面的不同,則第一個元素是唯一的,如果它與前面的不同,則結尾是唯一的。代碼可能如下所示:
#include <algorithm>
#include <iostream>
unsigned remove_dupe(int *data, unsigned n) {
if (n < 2) {
return n;
}
std::sort(data, data n);
unsigned output = data[0] != data[1];
for (unsigned input = output 1; input<n-1; input )
if (data[input] != data[input-1] && data[input] != data[input 1])
data[output ] = data[input];
if (data[n-1] != data[n-2]) {
data[output ] = data[n-1];
}
return output;
}
template <class T, std::size_t N>
void test(T (&arr)[N]) {
unsigned end = remove_dupe(arr, N);
for (int i=0; i<end; i )
std::cout << arr[i] << "\t";
std::cout << "\n";
}
int main() {
int arr0[] = {10, 20, 20, 30, 40, 40, 40, 50, 50};
int arr1[] = { 1, 2};
int arr2[] = { 1, 1};
test(arr0);
test(arr1);
test(arr2);
}
結果:
10 30
1 2
uj5u.com熱心網友回復:
另一個可能可用的選項是sort()陣列。完成此操作后,整個陣列中的所有重復值現在都是相鄰的。 您只需將元素[n]與元素[n 1]進行比較,看看它們是否相同。您現在可以在排序陣列的一次線性遍歷中查找和計算所有重復項。
排序是計算機科學中研究最多的一類演算法,可以開發非常有效的程序,依賴于以某種方式對事物進行排序。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/488630.html
下一篇:從多個排序陣列中收集前K個元素
