least number of digits without duplicates - c++

I am a C++ noob. I have a list of numbers that I put into a Vector. All numbers are 9 digit integers and are unique. I want to know what is the least amount of digits (starting from the right) that can be used to uniquily identify each number in the set. right now there are only 6 numbers, but the list could potentially grow into the thousands. I have posted my code thus far (not working.)
EDIT output is the following...
digit is 1
digit is 1
digit is 1
RUN FINISHED; exit value 0; real time: 0ms; user: 0ms; system: 0ms
This is mostly a learning exercise. Please be generous and explicit with your comments and solutions.
#include <iostream>
#include <vector>
#include <fstream>
#include <string>
#include <cstdlib>
#include <algorithm>
using namespace std;
int main() {
//declare stream variable and load vector with values
ifstream myfile("mydata.txt");
vector<int> myVector;
int num;
while (myfile >> num) {
myVector.push_back(num);
}
//sort and squack if there is a duplicate.
std::sort(myVector.begin(), myVector.end());
for (int i = 0; i < (myVector.size() - 1); i++) {
if (myVector.at(i) == myVector.at(i + 1)) {
printf("There are duplicate student numbers in the file");
exit(EXIT_FAILURE);
}
}
//if it get here, then there are no duplicates of student numbers
vector<int> newv;
int k = 1;
bool numberFound = false;
bool myflag = false;
while (numberFound == false) {
//loop through original numbers list and add a digit to newv.
for (int j = 0; j < myVector.size(); ++j) {
newv.push_back(myVector.at(j) % (10^k));
}
sort(newv.begin(), newv.end());
for (int i = 0; i < (newv.size() - 1); i++) {
if (newv.at(i) == newv.at(i + 1)) {
//there is a duplicate for this digit. Set flag.
myflag = true;
}
if (myflag == false) {
numberFound = true;
cout << "digit is " << k << endl;
} else {
k++;
}
}
}
// for (int i = 0; i < myVector.size(); i++) {
// cout << "||" << myVector.at(i) << "||" << endl;
// }
//
// for (int i = 0; i < newv.size(); i++) {
// cout << "---" << newv.at(i) << "---" << endl;
// }
return 0;
}

Check the below code.
#include <iostream>
#include <vector>
#include <fstream>
#include <string>
#include <cstdlib>
#include <algorithm>
#include <math.h>
using namespace std;
int main() {
//declare stream variable and load vector with values
ifstream myfile("mydata.txt");
vector<int> myVector;
int num;
while (myfile >> num) {
myVector.push_back(num);
}
//sort and squack if there is a duplicate.
std::sort(myVector.begin(), myVector.end());
for (int i = 0; i < (myVector.size() - 1); i++) {
if (myVector.at(i) == myVector.at(i + 1)) {
printf("There are duplicate student numbers in the file");
exit(EXIT_FAILURE);
}
}
//if it get here, then there are no duplicates of student numbers
vector<int> newv;
int k = 1;
bool numberFound = false;
bool myflag = false;
int p = 1;
while (numberFound == false) {
//loop through original numbers list and add a digit to newv.
newv.clear();
p = p * 10;
for (int j = 0; j < myVector.size(); ++j) {
newv.push_back(myVector[j] % p);
}
sort(newv.begin(), newv.end());
myflag = false;
for (int i = 0; i < (newv.size() - 1); i++) {
if ( newv[i] == newv[i+1]) {
//there is a duplicate for this digit. Set flag.
myflag = true;
break;
}
}
if (myflag == true){
k ++;
}else{
numberFound = true;
cout << "digit is " << k << endl;
break;
}
}
return 0;
}
Sample Input:
123451789
123456687
125456789
123456780
Output:
digit is 4

Related

for loop done without meeting the condition I set

#include <iostream>
#include <vector>
using namespace std;
int main()
{
int n = 5;
int nums[] = {0 ,1};
if (n == 0)
{
return 0;
} else if (n == 1)
{
return 1;
} else{
for (int i = 2; i < n + 1; i++)
{
cout << i << endl;
nums[i] = nums[i-2] + nums[i-1];
}
return nums[n]
}
return 0;
}
It is just a simple fibonacci array, but my code only gives stdout one time and it is two. FYI: this code may not be correct to compute the nth term of fibonacci array, but i am strugglling with this for loop.
I think the condition of i < n+1 is not meet, but why this for loop ends
nums[i] has size 2. You can't access nums[i] for i >= 2. An array doesn't grow. You can't change the size of an array. Use a std::vector. You've already included the header. A return statement finishes a function. In case of the main function it causes the program to stop. The return value of the main function by convention describes if the program was successful or errors occurred. You are returning
return nums[n];
That's probably not your intention. I assume you want to print the vector.
#include <iostream>
#include <vector>
using namespace std;
int main()
{
int n = 5;
std::vector<int> nums {0 ,1};
if (n == 0)
{
return 0;
} else if (n == 1) {
return 1;
} else {
nums.reserve(n + 1);
for (int i = 2; i < n + 1; i++)
{
cout << i << '\n';
nums.emplace_back(nums[i-2] + nums[i-1]);
}
for (const auto num : nums)
{
cout << num << '\n';
}
}
return 0;
}
it's because you can't access to nums[2] so the correct version of your code is :
#include <iostream>
#include <vector>
using namespace std;
int main()
{
int n = 5;
int nums[5] = {0 ,1};
if (n == 0)
{
return 0;
} else if (n == 1)
{
return 1;
} else{
for (int i = 2; i < n + 1; i++)
{
cout << i << endl;
nums[i] = nums[i-2] + nums[i-1];
}
return nums[n]
}
return 0;
}
you must provide estimated size to array or you will create vector or some dynamic array..
Your approach always give Segmentation fault;
#include <iostream>
#include <vector>
using namespace std;
int main()
{
int n = 5;
vector<int> nums(n+1);
nums[0]=0;
nums[1]=1;
if (n == 0)
{
return 0;
} else if (n == 1)
{
return 1;
} else{
for (int i = 2; i < n + 1; i++)
{
// cout << i << endl;
nums[i] = nums[i-2] + nums[i-1];
}
for(int i=0;i<n;i++)
{
cout<<nums[i]<<endl; }
}
return 0;
}
*/

How can I compare the elements in a vector?

I took a look online and none of the answers solves the problem I have comparing the elements from a vector.
I tried implementing a bool function but the problem is the same.
I am pretty new in c++ so please be patient!
PART2: First of all thank you.
So I changed my programm and created a bool function, the problem is now that it doesn get recognised before 5-6 tries.
#include <iostream>
#include <vector>
#include <time.h>
#include <stdlib.h>
#include <string>
using namespace std;
vector<int> input, compareMe, randomNumbers;
const unsigned int MAX_VEKTORSTELLEN = 5;
const unsigned int UPPER_GRENZE = 49;
const unsigned int LOWER_GRENZE = 1;
unsigned int i, j;
string output;
int random, anzahlRichtige, eingabe;
bool isEqual = false;
string lotto(vector<int>)
{
if (input[i] < LOWER_GRENZE || input[i] > UPPER_GRENZE)
{
output = "Die Zahlen muessen zwischen 1 und 49 liegen! \n";
input.pop_back();
}
else if (input.size() != MAX_VEKTORSTELLEN)
output = "Es muessen 6 Zahlen uebergeben werde! \n";
else if (isEqual == true)
output = "Es duerfen keine doppelten Zahlen vorkommen! \n";
else
for (i = 0; i <= MAX_VEKTORSTELLEN; i++)
srand((unsigned)time(NULL) <= UPPER_GRENZE && (unsigned)time(NULL) > 0);
random = rand();
randomNumbers.push_back(random);
return output;
}
bool compare()
{
compareMe = input;
for (i = 0; i < input.size(); i++)
for (j = 0; j < compareMe.size(); j++)
if (compareMe[j] == input[i])
isEqual = true;
return isEqual;
}
int main()
{
cout << "insert 6 numbers: ";
while (cin >> eingabe)
{
input.push_back(eingabe);
lotto(input);
compare();
cout << output;
for (i = 0; i < input.size(); i++) //Debug
cout << input[i] << ", ";
continue;
}
for (i = 0; i < input.size(); i++)
cout << input[i];
system("pause");
return 0;
}
From line 34 to line I didn´t finish to code but doesn´t really matter because I got stuck before.
All your loops in lotto are wrong. You go one past the end of your containers.
for (i = 0; i <= input.size(); i++)
// ^ !!!
It should be <.
You got this right in main.

C++, sort through array of numbers to find uniqueness

Say I have an array of 4 different numbers.
int numbers[4] = {50234, 50356, 50454, 50934};
How do you make a nested for loop in C++ to sort through these numbers from back to front in order to identify the required amount of digits needed for uniqueness?
From the example you can tell that you'll need 3 digits from the back to make sure no numbers contain similar tails of numbers. 50234, 50934 = 3 digits to have them unique = 502 and 509 respectively.
What would the for loop look like to go through each of these numbers one by one, number by number, and sort out identical numbers to reach an output of 3?
It would go like this:
4
6 - discard this number, it's not identical
4
4
Then:
3
5 - discard this number
3
Then:
2
9 Hurray! No similar numbers anymore, print out 3 being the answer.
I'm stumped and can't figure it out.
Any help would be greatly appreciated, thank you.
Say you start with
#include <unordered_set>
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
const std::vector<int> numbers{50234, 50356, 50454, 50934};
You can transform it into a vector of strings:
std::vector<std::string> string_numbers;
std::for_each(std::begin(numbers), std::end(numbers), [&](int n){ string_numbers.push_back(std::to_string(n)); });
Now we'll check the number of digits required, starting at 1:
size_t digits = 1;
while(true) {
At each iteration, we'll create an unordered_set
std::unordered_set<std::string> partials;
For each number, we'll attempt to place digits digits of it into the set:
for(const auto &s: string_numbers) {
if(s.size() <= digits) {
std::cout << "not unique" << std::endl;
return 0;
}
partials.insert(s.substr(0, digits));
}
If the size of the set is the size of the vector, we're done:
if(partials.size() == numbers.size()) {
std::cout << digits << " required" << std::endl;
return 0;
}
Otherwise, we need to increase the number of digits:
++digits;
}
}
Full code:
#include <unordered_set>
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
const std::vector<int> numbers{50234, 50356, 50454, 50934};
std::vector<std::string> string_numbers;
std::for_each(std::begin(numbers), std::end(numbers), [&](int n){ string_numbers.push_back(std::to_string(n)); });
size_t digits = 1;
while(true) {
std::unordered_set<std::string> partials;
for(const auto &s: string_numbers) {
if(s.size() <= digits) {
std::cout << "not unique" << std::endl;
return 0;
}
partials.insert(s.substr(0, digits));
}
if(partials.size() == numbers.size()) {
std::cout << digits << " required" << std::endl;
return 0;
}
++digits;
}
}
if you want to sort numbers so use one of sort algorithms let's say bubble sort. then check for uniqueness and store the unique values in a new array then print them:
we make our code for understanding and practice but in a real program we use libraries they are too much powerful and quick:
#include <iostream>
using std::cout;
using std::endl;
int main()
{
int numbers[4] = {50234, 50356, 50454, 50934};
// int numbers[4] = {50234, 50356, 50454, 50356};
for(int i(0); i < 4; i++)
{
for(int j(i + 1); j < 4; j++)
{
if(numbers[i] > numbers[j])
{
numbers[i] ^= numbers[j];
numbers[j] ^= numbers[i];
numbers[i] ^= numbers[j];
}
}
}
for(int i = 0; i < 4; i++)
cout << numbers[i] << ", ";
int nUniq = 0;
bool isUniq = true;
for(int i = 0; i < 4; i++)
{
isUniq = true;
for(int j(i + 1); j < 4; j++)
{
if(numbers[i] == numbers[j])
{
isUniq = false;
break;
}
}
if(isUniq)
nUniq++;
}
cout << nUniq << endl;
int* ptrUniq = new int[nUniq];
int k = 0;
for(int i = 0; i < 4; i++)
{
isUniq = true;
for(int j(i + 1); j < 4; j++)
{
if(numbers[i] == numbers[j])
{
isUniq = false;
break;
}
}
if(isUniq)
{
ptrUniq[k] = numbers[i];
k++;
}
}
cout << "\nhere are uniq values:\n\n";
for(int i = 0; i < nUniq; i++)
cout << ptrUniq[i] << ", ";
delete[] ptrUniq;
ptrUniq = NULL;
cout << endl << endl;
return 0;
}

Checking Sort of String Array: Output doesn't match expected

So I am trying to create this program to check the sort of a list of words to see whether they are in ascending, or descending order. I am copying the words from a file to an array of strings. I am told the regular comparison operators function the same with strings as they do with ints. However, when I run the program, it always outputs that the list is unordered (even when it is). I would greatly appreciate any help one could offer me. Thank you!
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
using namespace std;
int checkArraySort(int array_max, string arr[]);
int main(void)
{
const int array_max = 20;
string arr[array_max];
int d;
ifstream myfile_in;
myfile_in.open ("words_in.txt");
string line;
for(int i = 0; i < array_max; i++)
{
getline(myfile_in, line);
}
d = checkArraySort(array_max, arr);
if(d == -1)
{
cout << "The array is sorted in descending order!" << endl;
}
if(d == 0)
{
cout << "The array is not sorted!" << endl;
}
if(d == 1)
{
cout << "The array is sorted in ascending order!" << endl;
}
myfile_in.close();
return 0;
}
int checkArraySort(int array_max, string arr[])
{
bool y = false;
int j = 0;
for(int i = 0; i < array_max; i++)
{
if(arr[i] < arr[i-1])
{
j++;
}
if(j == (array_max))
{
y = true;
return -1;
}
}
j = 0;
for(int i = 0; i < array_max; i++)
{
if(arr[i] > arr[i-1])
{
j++;
}
if(j == (array_max))
{
y = true;
return 1;
}
}
if(y = false)
{
return 0;
}
}
if(y = false)
should be
if(y == false)

Max Sum Of Integers

EDIT: solved! I was treating negative numbers test case as 0, instead of having the output be negative as well. thanks for the help!
Here is the challenge description: https://www.codeeval.com/open_challenges/17/
I keep getting a partially solved score. I want to know why. As in my eyes, this code works. And I believe that it is O(N) time. Thanks for looking!
Here is my code:
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <vector>
#include <string>
#include <sstream>
using namespace std;
int max(int a, int b)
{
if (a > b)
return a;
else return b;
}
int maxSubArray(vector<int> values)
{
int max_so_far = values[0];
int curr_max = values[0];
for(int i = 1; i < values.size(); ++i)
{
curr_max = max(values[i], curr_max + values[i]);
max_so_far = max(max_so_far, curr_max);
}
return max_so_far;
}
int main(int argc, char *argv[])
{
std::vector<vector<int> > Values; //to hold the values of the stock price change
ifstream file(argv[1]);
std::string line; //for the txt file input
int value = 0; //for holding the value of stock change
while (std::getline(file, line))
{
int pos = 0;
if(line.length() == 0)
continue;
else
{
std::istringstream iss(line);
std::vector<int> list; // temporary list of values to be pushed back into the 2-d vector
while (iss >> value)
{
list.push_back(value);
}
Values.push_back(list);
}
}
for(int i = 0; i < Values.size(); ++i)
{
cout << maxSubArray(Values[i]);
cout << endl;
}
/*
cout << " Printing the values : " << endl;
for (int j = 0; j < Values.size(); ++j)
{
for (int k = 0; k < Values[j].size(); ++k)
cout << Values[j][k] << " ";
cout << endl;
}
*/
return 0;
}
so I swapped out some code now. I get better score but I it's still a partial.
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <vector>
using namespace std;
int max(int a, int b)
{
if (a > b)
return a;
else return b;
}
int maxSubArray(vector<int> values)
{
int max_so_far = values[0];
int curr_max = values[0];
if (curr_max < 0)
{
curr_max = 0;
max_so_far = 0;
}
for(int i = 1; i < values.size(); ++i)
{
curr_max = max(values[i], curr_max + values[i]);
curr_max = max(curr_max, 0);
max_so_far = max(max_so_far, curr_max);
}
return max_so_far;
}
int main(int argc, char *argv[])
{
std::vector<vector<int> > Values; //to hold the values of the stock price change
ifstream file(argv[1]);
std::string line; //for the txt file input
std::string token; //for the subtring that will be converted from char to int
int value = 0; //for holding the value of stock change
int count = 0;// for holding how many total cases
while (!file.eof())
{
int pos = 0;
getline(file, line);
if(line.length() == 0)
continue;
else
{
std::vector<int> list; // temporary list of values to be pushed back into the 2-d vector
while ((pos = line.find(",")) != std::string::npos )
{
token = line.substr(0,pos);
value = atoi(token.c_str());
line.erase(0, pos + 1);
list.push_back(value);
}
value = atoi(line.c_str());
list.push_back(value);
Values.push_back(list);
++count;
}
}
for(int i = 0; i < Values.size(); ++i)
{
cout << maxSubArray(Values[i]);
cout << endl;
}
cout << " Printing the values : " << endl;
for (int j = 0; j < Values.size(); ++j)
{
for (int k = 0; k < Values[j].size(); ++k)
cout << Values[j][k] << " ";
cout << endl;
}
return 0;
}
Why are you passing the vector by value here?
int maxSubArray(vector<int> values)
That looks like a significant optimization opportunity.
I think you don't read the problem exactly right. When they say 'all contiguous sub ararys', they mean you have to take the max over all i andj of for(idx = i; i < j; ++i) { total += vec[idx]; }. Right now your code basically assumes i = 0 which isn't what you are supposed to do.
Just from looking at the output examples they provide, I can see that your code isn't going to give the answer that they expect.
it seems right, the only thing I can think of is that when the list gets long, your result can overflow, so change int to long long.
Besides technical optimizations suggested in other answers, concerning the algorithm, i think a little fix can make your algorithm work. When curr_max drops to a negative value, due to encountering a negative integer that exceeds curr_max, you can simply drop all the previous integers including the current value and start over. This fix is simple, you can add one line to your loop like this:
for(int i = 1; i < values.size(); ++i)
{
curr_max = max(values[i], curr_max + values[i]);
curr_max = max(curr_max, 0); // <---------------- add this line
max_so_far = max(max_so_far, curr_max);
}