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

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;
}

Related

printing the below pattern using just one loop

ive got the below code to print a pattern (attached below). However i'd like to just use one loop
#include<iostream>
using namespace std;
int main(){
int n;
cin>>n;
for(int i=1;i<=n;i++){
for(int j=1;j<=i;j++){
cout<<"*";
}
for(int j=1;j<=n-i;j++){
if(j%2!=0){
cout<<"_";
}else{
cout<<".";
}
}
cout<<endl;
}
for(int i=1;i<n;i++){
for(int j=1;j<=n-i;j++){
cout<<"*";
}
for(int j=1;j<=i;j++){
if(j%2==0){
cout<<".";
}else{
cout<<"_";
}
}
cout<<endl;
}
}
when n = 5, heres the output.
*_._.
**_._
***_.
****_
*****
****_
***_.
**_._
*_._.
how do i just make this into one single loop
Try this and see how it does what you want to understand the step you did not find on your own:
#include<iostream>
using namespace std;
int main() {
int n;
cin >> n;
for (int i = 1; i <= n*2-1; i++) {
if (i <= n)
{
for (int j = 1; j <= i; j++) {
cout << "*";
}
for (int j = 1; j <= n - i; j++) {
if (j % 2 != 0) {
cout << "_";
}
else {
cout << ".";
}
}
cout << endl;
}
else
{
for (int j = 1; j <= n*2 - i; j++) {
cout << "*";
}
for (int j = 1; j <= i-n; j++) {
if (j % 2 == 0) {
cout << ".";
}
else {
cout << "_";
}
}
cout << endl;
}
}
}
I'd like to just use one loop.
I'll take it literally and show a starting point for a possible solution.
// Let's start by figuring out some dimensions.
int n;
std::cin >> n;
int height = 2 * n - 1;
int area = n * height;
// Now we'll print the "rectangle", one piece at a time.
for (int i = 0; i < area; ++i)
{ // ^^^^^^^^
// Extract the coordinates of the char to be printed.
int x = i % n;
int y = i / n;
// Assign a symbol, based on such coordinates.
if ( x <= y and x <= height - y - 1 )
{ // ^^^^^^ ^^^^^^^^^^^^^^^^^^^ Those are the diagonals.
std::cout << '*'; // This prints correctly the triangle on the left...
}
else
{
std::cout << '_'; // <--- But of course, something else should done here.
}
// End of row.
if ( x == n - 1 )
std::cout << '\n';
}
If you look at the pattern, then you can see a sort of "triangles". And this already gives a hint for the solution. Use a triangle function.
Please read about it here.
Then you will notice that always the "aboslute"-function, in C++ std::abs, is involved.
But first of all, it is easily visible that the number rows to print is always the width of a triangle * 2.
And the number of charcters in the pattern, can be calculated by applying the triangle function. Example for width 5:
Number of stars number of dashdot
Row width-abs(row-width) abs(row-width)
1 1 4
2 2 3
3 3 2
4 4 1
5 5 0
6 4 1
7 3 2
8 2 3
9 1 4
And this can be implemented easily now.
#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std::string_literals;
int main() {
// Get the max width of the pattern and perform a short input validation
int maxWidth{};
if ((std::cin >> maxWidth) and (maxWidth > 0)) {
// The number of rows for the pattern is dependent on the width. It is a simple relation
const int numberOfRows = 2 * maxWidth;
// Show all rows
for (int row = 1; row < numberOfRows; ++row) {
// Use triangle formular to create star pattern
std::string starPattern(maxWidth - std::abs(row - maxWidth), '*');
// Create dashDot pattern
std::string ddp(std::abs(row - maxWidth), '\0');
std::generate(ddp.begin(), ddp.end(), [i = 0]() mutable { return i++ % 2 ? '.' : '_'; });
// Show output
std::cout << (starPattern+ddp) << '\n';
}
}
else std::cout << "\n*** Error: Invalid input\n\n";
}
Of course you can also create the whole pattern wit std::generate.
Maybe it is too complex for now.
And less understandable.
See:
#include <iostream>
#include <string>
#include <cmath>
#include <algorithm>
#include <vector>
int main() {
// Get the max width of the pattern and perform a short input validation
if (int width{}; (std::cin >> width) and (width > 0)) {
std::vector<std::string> row(2 * width - 1);
std::for_each(row.begin(), row.end(), [&, r = 1](std::string& s) mutable {
s = std::string(width - std::abs(r - width), '*');
std::string ddp(std::abs(r++ - width),'\0');
std::generate(ddp.begin(), ddp.end(), [&, i = 0]() mutable{ return i++ % 2 ? '.' : '_'; });
s += ddp; std::cout << s << '\n'; });
}
else std::cout << "\n*** Error: Invalid input\n\n";
}

How does this loop work (Check Duplicate in array loop)

Beginner programmer here can someone please explain to me how this loop works.
How can the loop detect the duplicate element in the array?
sorry for the simple question.
#include <iostream>
using namespace std;
int main()
{
int num[5];
int numSize = sizeof(num) / sizeof(num[0]);
for(int i = 0; i < numSize; i++)
{
cout << "Enter number : ";
cin >> num[i];
if(i >= 0)
{
for(int j = 0 ; j < numSize; j++)
{
if(num[i] == num[j] && (i != j))
{
i--;
j++;
}
}
}
}
for(int p = 0; p < numSize; p++)
cout << num[p] << " ";
}
Avoid indexing when it is possible. It is not final solution but it may show you right direction.
#include <iostream>
#include <algorithm>
int main()
{
int num[] = { 0, 5, 6, 8, 0, 2, 5, 8 };
std::sort(std::begin(num), std::end(num));
auto it = std::begin(num);
while(1) {
it = std::adjacent_find(it, std::end(num));
if(it != std::end(num)) {
std::cout << "Double pairs " << *it << " and " << *(it+1) << std::endl;
++it;
}
else {
break;
}
}
return 0;
}
Output:
Double pairs 0 and 0
Double pairs 5 and 5
Double pairs 8 and 8

Square Root Code C++ without sqrt()

I have to create a code where the user inputs a number which is a perfect square, and I have to show its root. I've made this code, but I'm getting Segmentation Fault 11 , in this piece: int j = squareRootVector[i];
squareRoot.push_back(j);.
I can't change the code too much, so is there a way that I can do that?
#include <iostream>
#include <vector>
using namespace std;
int main() {
cout <<
"Enter the number:\n";
int input;
int number = input;
int divider = 2;
vector<int> squareRootVector;
vector<int> squareRoot;
cin >> number;
for(int divider = 2; number > 1; divider++) {
while((number % divider) == 0) {
number /= divider;
cout << number << endl;
squareRootVector.push_back(divider);
}
}
for(int i = 0; i < squareRootVector.size(); i++) {
cout << squareRootVector[i] << " ";
/*******PROBLEM*******/
if(squareRootVector[i] == squareRootVector[i+1]) {
int j = squareRootVector[i];
squareRoot.push_back(j);
}
/*********************/
}
int root;
for (int i = 0; squareRoot.size(); i++) {
root = root * squareRoot[i];
}
cout << "Square Root of " << input << " is: " << root << endl;
return 0;
}
The behaviour on accessing squareRootVector[i+1] with i just one below size (which your loop constaint allows) is undefined.
Consider writing
for (std::size_t i = 1; i < squareRootVector.size(); i++) {
instead, and rebasing the for loop body accordingly. I've also slipped in a change of type for i.
Shortly, the problem is that the last cycle in the last "for":
for(int i = 0; i < squareRootVector.size(); i++)
has the following line in it:
squareRootVector[i] == squareRootVector[i+1];
This is an "out of limits" error: squareRootVector only has squareRootVector.size() elements (let's say n), and the elements are indexed from 0 to n-1.
squareRootVector[i+1] in the last cycle points one element after the last one of squareRootVector, which is undefined behavior.
Using vector::iterator is proper way.
for(vector<int>::iterator it = squareRootVector.begin(); it != squareRootVector.end(); ++it)
{
if( (it+1) == squareRootVector.end() )
{
//what to do if there's no next member???
break;
}
if( *it == *(it+1) )
{
squareRoot.push_back(*it);
}
}
Thanks for the answers, guys. I've ended up with this code:
#include <iostream>
#include <vector>
using namespace std;
int main() {
cout << "Enter the number:\n";
int input = 0;
int number = 0;
cin >> input;
number = input;
int divider = 2;
vector<int> squareRootVector;
vector<int> squareRoot;
for(int divider = 2; number > 1; divider++) {
while((number % divider) == 0) {
number /= divider;
squareRootVector.push_back(divider);
}
}
int vectorSize = squareRootVector.size() - 1;
for(int i = 0; i < vectorSize; i++) {
if(squareRootVector[i] == squareRootVector[i+1]) {
int j = squareRootVector[i];
squareRoot.push_back(j);
}
}
int root = 1;
for (int i = 0; i < squareRoot.size(); i++) {
root = root * squareRoot[i];
}
cout << "Square Root of " << input << " is " << root << endl;
return 0;
}

least number of digits without duplicates

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

Treating an array of bools as though incrementing in binary [duplicate]

This question already has answers here:
Bitset in C++, about continuously add
(2 answers)
Closed 8 years ago.
I'm trying to create a loop that changes the values in a boolean array so that it looks like the array is incrementing in binary values.
For example
1st iteration [0|0|0]
2nd iteration [0|0|1]
3rd iteration [0|1|0]
4th iteration [0|1|1]
etc.
This array is dynamic, however, and can be different sizes. So whatever loop I write would need to also work on an array with five elements instead of three.
Apologies for not having any starting code, but I've been frustrating myself with this for hours and still can't even come up with how to begin.
Try this. This may not be complete but you could do something similar
#include <iostream>
using namespace std;
void increment(bool* array, int len)
{
for (int i = len - 1; i >= 0; --i)
{
if ( ! array[i])
{
array[i] = true;
return;
}
array[i] = false;
}
}
int main()
{
bool* array = new bool[10];
for (int i = 0; i < 5; ++i)
{
increment(array, 10);
for (int i = 0; i < 10; ++i)
{
cout << (array[i] ? 1 : 0) << "|";
}
cout << endl;
}
return 0;
}
#include <iostream>
#include <cmath>
#include <memory>
using namespace std;
void ArrayIterate(int);
void printArray(bool*,int);
void ArrayIterate(int arraySize)
{
int decimal_value = 0;
int decimal_place_value = 0;
bool* boolArray = new bool(arraySize);
long double max_itr = pow(2,arraySize);
for (int i = 0; i < max_itr ; ++i)
{
decimal_value = i;
// set array values
for ( int k = arraySize - 1; k >= 0; --k)
{
decimal_place_value = pow(2,k);
if( decimal_value != 0 && decimal_value / decimal_place_value >= 1 )
{
boolArray[k] = true;
decimal_value -= decimal_place_value;
}
else
boolArray[k] = false;
}
printArray(boolArray,arraySize);
cout << " = " << i << endl; ;
}
delete boolArray;
return;
}
void printArray(bool* boolArray, int arraySize)
{
cout << "\t";
for(int i = arraySize - 1; i >= 0; --i)
cout << ((boolArray[i] == true)? 1 : 0) << " ";
return;
}
int main()
{
cout << "\n\n";
ArrayIterate(4);
cout << "\n\n" << endl;
return 0;
}