为了找到从l
到r
索引的数组中不同数字的数量,我编写了一个代码块,如:
int a[1000000];
//statements to input n number of terms from user in a.. along with l and r
int count=r-l+1; //assuming all numbers to be distinct
for(; l<=r; l++){
for(int i=l+1; i<=r; i++){
if(a[l]==a[i]){
count--;
break;
}
}
}
cout<<count<<'\n';
解释
对于数组说,a = 5 6 1 1 3 2 5 7 1 2
十个元素。如果我们想检查[1]和[8]之间的第二个和第九个元素(包括两者)之间的不同数字的数量,我试图实现的逻辑将首先取count = 8(元素数量)被认为是)然后它从6的[1]开始并检查其后的任何其他6,如果它确实找到,它将计数减1并继续行中的下一个数字。因此,如果在那之后再出现6,则不会包含两次。
问题我尝试过小型测试用例,但是有效。但是当我尝试使用更大的数据时,它不起作用,所以我想知道我的逻辑会在哪里失败?
更大的数据,如与程序的其他部分集成然后使用。哪个输出不正确
答案 0 :(得分:4)
您可以尝试使用std::set
基本思路是将所有元素添加到新集合中,然后输出集合的大小。
#include <iostream>
#include <vector>
#include <set>
using namespace std;
int main()
{
int l = 1, r = 6;
int arr[] = {1, 1, 2, 3, 4, 5, 5, 5, 5};
set<int> s(&arr[l], &arr[r + 1]);
cout << s.size() << endl;
return 0;
}
答案 1 :(得分:2)
这是一个不使用std::set
的答案,尽管该解决方案可能更简单。
#include <algorithm>
#include <vector>
int main()
{
int input[10]{5, 6, 1, 1, 3, 2, 5, 7, 1, 2}; //because you like raw arrays, I guess?
std::vector<int> result(std::cbegin(input), std::cend(input)); //result now contains all of input
std::sort(std::begin(result), std::end(result)); //result now holds 1 1 1 2 2 3 5 5 6 7
result.erase(std::unique(std::begin(result), std::end(result)), std::end(result)); //result now holds 1 2 3 5 6 7
result.size(); //gives the count of distinct integers in the given array
}
如果你进入那里,那就是live on Coliru。
-
编辑:此处,还有一个简短版本的解决方案。
#include <set>
int main()
{
int input[10]{5, 6, 1, 1, 3, 2, 5, 7, 1, 2}; //because you like raw arrays, I guess?
std::set<int> result(std::cbegin(input), std::cend(input));
result.size();
}
答案 2 :(得分:2)
要问这类问题的第一个问题是值的可能范围是多少。如果数字范围 override func motionEnded(motion: UIEventSubtype,
withEvent event: UIEvent?) {
if motion == .MotionShake{
let randomNumber = arc4random_uniform(2) + 1
print(randomNumber)
if randomNumber == 1 {
labelOne.text = "Sorry!"
labelTwo.text = "You Have Not Won This Time"
labelThree.text = "Better Luck Tomorrow"
}
if randomNumber == 2 {
labelOne.text = "Winner!"
labelTwo.text = "1 x Shot Patron Cafe"
labelThree.text = "Show at the bar to claim."
}
let xPosition = stampView.frame.origin.x
//View will slide 20px up
let yPosition = stampView.frame.origin.y - 100
let height = stampView.frame.size.height
let width = stampView.frame.size.width
UIView.animateWithDuration(3.0, animations: {
self.stampView.frame = CGRectMake(xPosition, yPosition, height, width)
})
print("SHAKEN!")
}
}
是&#34;相当小&#34;,则可以使用大小为N
的布尔数组来指示是否存在与索引对应的数字。您从N
迭代到l
,设置标志,如果标志尚未设置,则递增计数器。
r
就复杂性而言,这种方法和基于集合的方法都是O(n),但是这种方法更快,因为不涉及散列。对于较小的count = 0;
for(int i=l; i<=r; i++) {
if (! isthere[arr[i]]) {
count++;
isthere[arr[i]] = TRUE;
}
}
,例如0到255之间的数字,很可能这也可能是内存密集度较低。对于较大的N
,例如,如果允许任何32位整数,则基于集合的方法更合适。
答案 3 :(得分:1)
你说你不介意另一个解决方案。所以这就是。它使用set - 一种只存储唯一元素的结构。顺便说一句,在更大的数据上 - 它将比具有两个周期的解决方案快得多。
FroslagOpslag
答案 4 :(得分:1)
在下面的过程中,我给出了计算唯一数字的过程。在这种技术中,您只需在数组中获得唯一元素。此过程将使用垃圾值更新您的数组。所以在这个过程中你不能再使用这个数组(我们将使用)。此数组将使用不同的元素自动调整大小。
#include <stdio.h>
#include <iostream>
#include <algorithm> // for using unique (library function)
int main(){
int arr[] = {1, 1, 2, 2, 3, 3};
int len = sizeof(arr)/sizeof(*arr); // finding size of arr (array)
int unique_sz = std:: unique(arr, arr + len)-arr; // Counting unique elements in arr (Array).
std:: cout << unique_sz << '\n'; // Printing number of unique elements in this array.
return 0;
}
如果你想解决这个问题(我之前说过),你可以按照这个过程。你可以通过在另一个数组中处理你的数组来处理这个问题。
#include <stdio.h>
#include <iostream>
#include <algorithm> // for using copy & unique (library functions)
#include <string.h> // for using memcpy (library function)
int main(){
int arr[] = {1, 1, 2, 2, 3, 3};
int brr[100]; // we will copy arr (Array) to brr (Array)
int len = sizeof(arr)/sizeof(*arr); // finding size of arr (array)
std:: copy(arr, arr+len, brr); // which will work on C++ only (you have to use #include <algorithm>
memcpy(brr, arr, len*(sizeof(int))); // which will work on C only
int unique_sz = std:: unique(arr, arr+len)-arr; // Counting unique elements in arr (Array).
std:: cout << unique_sz << '\n'; // Printing number of unique elements in this array.
for(int i=0; i<len; i++){ // Here is your old array, that we store to brr (Array) from arr (Array).
std:: cout << brr[i] << " ";
}
return 0;
}
答案 5 :(得分:0)
就个人而言,我只是使用标准算法
mainPage
这显然依赖于允许修改数组(任何重复项都移动到#include<algorithm>
#include <iostream>
int main()
{
int arr[] = {1, 1, 2, 3, 4, 5, 5, 5, 5};
int *end = arr + sizeof(arr)/sizeof(*arr);
std::sort(arr, end);
int *p = std::unique(arr, end);
std::cout << (int)(p - arr) << '\n';
}
的末尾)。但是如果需要的话,可以很容易地创建一个数组的副本并在副本上工作。
答案 6 :(得分:0)
TL; DR:使用此:
template<typename InputIt>
std::size_t countUniqueElements(InputIt first, InputIt last) {
using value_t = typename std::iterator_traits<InputIt>::value_type;
return std::unordered_set<value_t>(first, last).size();
}
有两种方法:
将所有内容插入集合,对集合计数。因为您不关心顺序,所以可以使用比std::unordered_set
更快的std::set
。 std::set
被实现为执行大量分配的树,因此它可能很慢。
使用std::sort
。如果要保留原始数组,则需要对其进行复制。
这是一个完整的例子。
#include <algorithm>
#include <cstdint>
#include <vector>
#include <unordered_set>
#include <iostream>
template<typename RandomIt>
std::size_t countUniqueElementsSort(RandomIt first, RandomIt last) {
if (first == last)
return 0;
std::sort(first, last);
std::size_t count = 1;
auto val = *first;
while (++first != last) {
if (*first != val) {
++count;
}
val = *first;
}
return count;
}
template<typename InputIt>
std::size_t countUniqueElementsSet(InputIt first, InputIt last) {
using value_t = typename std::iterator_traits<InputIt>::value_type;
return std::unordered_set<value_t>(first, last).size();
}
int main() {
std::vector<int> v = {1, 3, 4, 4, 3, 6};
std::cout << countUniqueElementsSet(v.begin(), v.end()) << "\n";
std::cout << countUniqueElementsSort(v.begin(), v.end()) << "\n";
int v2[] = {1, 3, 4, 4, 3, 6};
std::cout << countUniqueElementsSet(v2, v2 + 6) << "\n";
std::cout << countUniqueElementsSort(v2, v2 + 6) << "\n";
}
在排序版本中使用该循环应该比std::unique
快。
2的复杂度比1差。-平均情况为O(N)vs O(N log N)。但是它避免了分配,因此对于较小的数组或已排序或大部分已排序的数组,最终可能会更快。
您绝对应该不使用std::set
,并且可能不使用std::unique
(尽管这样做确实会导致更少的代码行,并且对性能取决于您)。
无论如何,在大多数情况下,您应该使用设置的版本-它更简单,并且在几乎所有情况下都应该更快。
bool
数组而不是unordered_set
。