Distinct numbers in c++ - c++

I want to start by saying I am new to programming. I have a problem with writing a list of distinct numbers from another list in c++. Let's say I have a list l1 = {1, 12, 2, 4, 1, 3, 2} and I want to create a new list that looks like this l2 = {1, 12, 2, 4, 3}...
This is what I wrote:
#include <iostream>
using namespace std;
int main() {
int l1[100], l2[100], length, length1 = 0, i, j, a = 0;
cin >> length; //set the length
for (i = 0; i < length; i++) {
cin >> l1[i]; //add numbers to the list
}
l2[0] = l1[0]; //added the first number manually
for (i = 0; i < length; i++) {
length1++;
a = 0;
for (j = 0; j < length1; j++) {
if (l1[i] != l2[j]) //this checks numbers in the second list
a = 1; // and if they aren't found a gets the value
} //1 so after it's done checking if a is 1 it
if (a == 1) //will add the number to the list, but if the
l2[j] = l1[i]; //number is found then a is 0 and nothing happens,
} // SUPPOSEDLY
for (j = 0; j < length1; j++) {
cout << l2[j] << " ";
}
}
The output of this is 1 -858993460 12 2 4 1 3 so obviously I did something very wrong. I'd welcome any suggestion you might have, I don't necessarily need a solution to this, I just want to get unstuck.
Thanks a lot for taking time to reply to this.

std::sort(l1, l1 + 100);
int* end_uniques = std::unique(l1, l1 + 100);
std::copy(l1, end_uniques, l2);
size_t num_uniques = end_uniques - l1;
This is O(N log N) instead of your O(N^2) solution, so theoretically faster. It requires first sorting the array l1 (in-place) to let std::unique work. Then you get a pointer to the end of the unique elements, which you can use to copy to l2 and of course get the count (because it may be less than the full size of 100 of course).

Most Important : This solution assumes that we've to preserve order
Well....
try out this one....
I've changed identifiers a bit ( of course that's not gonna affect the execution )
It'll just help us to identify what is the sake of that variable.
Here's the code
#include <iostream>
using namespace std;
int main()
{
int Input[100], Unique[100], InSize, UniLength = 0;
cin >> InSize;
for (int ii = 0 ; ii < InSize ; ii++ )
{
cin >> Input[ii];
}
Unique[0] = Input[0];
UniLength++;
bool IsUnique;
for ( int ii = 1 ; ii < InSize ; ii++ )
{
IsUnique=true;
for (int jj = 0 ; jj < UniLength ; jj++ )
{
if ( Input[ii] == Unique[jj] )
{
IsUnique=false;
break;
}
}
if ( IsUnique )
{
Unique[UniLength] = Input[ii];
UniLength++;
}
}
for ( int jj = 0 ; jj < UniLength ; jj++ )
{
cout << Unique[jj] << " ";
}
}
You were inserting Unique element at it's original index in new array..... and in place of those elements which were duplicate.... you was not doing any kind of shifting.... i.e. they were uninitialized..... and were giving something weird like -858993460
I appreciate above mentioned two answers but again..... I think this question was placed on hackerrank.... and unqiue_array() doesn't work there.....
Added
Of course we can only add Unique elements to our Input array..... but... this solution works..... Moreover we have 2 seconds of execution time limit.... and just 100 elements..... Keeping in mind.... that Big Oh Notation works good for really large Inputs .... Which is not case here....So there's really no point looking at time complexity....... What I'll choose is the algorithm which is easy to understand.
I hope this is what you were looking for...
Have a nice day.

Related

C++ Largest number in array. Positive and negative

I have a task to print maximum int of matrix second line.
Example input:
3 2 (n, m)
-1 -2 <- 1 line
4 5 <- 2 line
2 6 <- 3 line
Max int in second line is 5. My program prints it. But if second line would be -100 -150, it not works. Sure it is because I have max = 0, but I don't know how to use it properly. I'm a student. Thanks in advance.
It is my code:
#include <iostream>
using namespace std;
int main() {
int n, m, max = 0;
cin >> n >> m;
int matrix[10][10];
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
cin >> matrix[i][j];
}
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (matrix[1][j] > max) {
max = matrix[1][j];
}
}
}
if (max == 0 || n == 1) {
cout << "No";
} else {
cout << max;
}
}
And code works pretty good, unless there are negative numbers in second line
You are correct to suspect max = 0;. Why is that a problem? Well, first, perhaps you should try to explain to your rubber duck why it is correct. As you try to do so, you are likely to express an intent along the lines of "this value will not make it through the checks" or "this value will be replaced in the first iteration of the loop". Why? "Because matrix[1][j] > max will be true, so... Hold on, wasn't the problem when matrix[1][j] > 0 is false? So when max is 0, um... problem?"
The overall strategy is valid, but there is a requirement that max be initialized to a low enough value. There are two common strategies I can think of at the moment.
Use a value that is as low as possible for the type you are using. That is:
int max = std::numeric_limits<int>::lowest();
Use the value from the first iteration of the loop. No need to provide a value that is just going to be replaced anyway. There are some caveats for this, though. The most relevant for your example can be expressed as a question: what if there is no first iteration? (Perhaps there is only one row? Perhaps there are no columns?) Also, you would need to initialize max between your loops, after the matrix has been given values.
int max = (n > 1 && m > 0) ? matrix[1][0] : /* what value do you want here? */;

Shifting Objects Up in an Array

I'm creating a program that creates an array of objects in random positions in an array size 8. Once created, I need them to sort so that all the objects in the array are shifted up to the top, so no gaps exist between them. I'm almost there, but I cannot seem to get them to swap to index 0 in the array, and they instead swap to index 1. Any suggestions? (Must be done the way I'm doing it, not with other sorting algorithms or whatnot)
#include <iostream>
#include <string>
#include <ctime>
using namespace std;
struct WordCount {
string name = "";
int count = 0;
};
int main() {
cout << "Original random array: " << endl;
srand(static_cast<int>(time(0)));
int i = 0;
WordCount wordArr[8];
while (i < 4) {
int randomNum = 0 + (rand() % static_cast<int>(7 + 1));
if(wordArr[randomNum].name == "") {
wordArr[randomNum].name = "word" + static_cast<char>(i);
wordArr[randomNum].count = i;
i++;
}
}
int j = 0;
while (j < 8) {
cout << wordArr[j].name << " " << wordArr[j].count << endl;
j++;
}
cout << "\n\nSorted array: " << endl;
for (int i = 7; i >= 0; i--) {
for (int j = 0; j <= 7; j++) {
if (wordArr[i].name != "") {
if (wordArr[j].name == "") {
WordCount temp = wordArr[i];
wordArr[i] = wordArr[j];
wordArr[j] = temp;
}
}
}
}
int k = 0;
while (k < 8) {
cout << wordArr[k].name << " " << wordArr[k].count << endl;
k++;
}
return 0;
}
If I understand your requirement correctly, you want to move all the non-blank entries to the start of the array. To do this, you need an algorithm like this for example:
for i = 0 to 7
if wordArr[i].name is blank
for j = i + 1 to 7
if wordArr[j].name is not blank
swap [i] and [j]
break
So, starting from the beginning, if we encounter a blank entry, we look forward for the next non-blank entry. If we find such an entry, we swap the blank and non-blank entry, then break to loop again looking for the next blank entry.
Note, this isn't the most efficient of solutions, but it will get you started.
Note also I'd replace the 4 and 8 with definitions like:
#define MAX_ENTRIES (8)
#define TO_GENERATE_ENTRIES (4)
Finally:
wordArr[randomNum].name = "word" + static_cast<char>(i);
That will not do what you want it to do; try:
wordArr[randomNum].name = "word" + static_cast<char>('0' + i);
To append the digits, not the byte codes, to the end of the number. Or perhaps, if you have C++11:
wordArr[randomNum].name = "word" + std::to_string(i);
I see couple of problems.
The expression "word" + static_cast<char>(i); doesn't do what you are hoping to do.
It is equivalent to:
char const* w = "word";
char const* p = w + i;
When i is 2, p will be "rd". You need to use std::string("word") + std::to_string(i).
The logic for moving objects with the non-empty names to objects with empty names did not make sense to me. It obviously does not work for you. The following updated version works for me:
for (int i = 0; i <= 7; ++i) {
// If the name of the object at wordArr[i] is not empty, move on to the
// next item in the array. If it is empty, copy the next object that
// has a non-empty name.
if ( wordArr[i].name == "") {
// Start comparing from the object at wordArr[i+1]. There
// is no need to start at wordArr[i]. We know that it is empty.
for (int j = i+1; j <= 7; ++j) {
if (wordArr[j].name != "") {
WordCount temp = wordArr[i];
wordArr[i] = wordArr[j];
wordArr[j] = temp;
}
}
}
}
There was two problems as :
wordArr[randomNum].name = "word" + static_cast<char>(i); this is not what your are looking for, if you want that your names generate correctly you need something like this :
wordArr[randomNum].name = "word " + std::to_string(i);
Your sorting loop does not do what you want, it's just check for the "gaps" as you said, you need something like this :
for (int i = 0; i < 8; ++i) {
for (int j = i+1; j < 8; ++j) {
if (wordArr[i].name == "" || (wordArr[i].count < wordArr[j].count)) {
WordCount temp = wordArr[i];
wordArr[i] = wordArr[j];
wordArr[j] = temp;
}
}
}
Your algorithm sorts the array, but then looses the sorting again.
You want to swap elements only when i > j, in order to push elements to the top only. As a result, you need to change this:
if (wordArr[j].name == "")
to this:
if (wordArr[j].name == "" && i > j)
Consider this array example:
0
ord 1
0
0
rd 2
word 0
d 3
0
Your code will sort it to:
d 3
ord 1
word 0
rd 2
0
0
0
0
but when i = 3, it will try to populate the 5th cell, and it will swap it with rd 2, which is not what we want.
This will push rd 2 down, but we don't want that, we want gaps (zeroes) to go to the end of the array, thus we need to swap eleemnts only when they are going to go higher, not lower, which is equivalent to say when i > j.
PS: If you are a beginner skip that part.
You can optimize the inner loop by using one if statement and a break keyword, like this:
for (int j = 0; j <= 7; j++) {
if (wordArr[i].name != "" && wordArr[j].name == "" && i > j) {
WordCount temp = wordArr[i];
wordArr[i] = wordArr[j];
wordArr[j] = temp;
break;
}
}

c++:Hackerank:Error in taking input

This is a part of my question.I tried many times but couldn't get the answer
Problem Statement
You are given a list of N people who are attending ACM-ICPC World Finals. Each of them are either well versed in a topic or they are not. Find out the maximum number of topics a 2-person team can know. And also find out how many teams can know that maximum number of topics.
Note Suppose a, b, and c are three different people, then (a,b) and (b,c) are counted as two different teams.
Input Format
The first line contains two integers, N and M, separated by a single space, where N represents the number of people, and M represents the number of topics. N lines follow.
Each line contains a binary string of length M. If the ith line's jth character is 1, then the ith person knows the jth topic; otherwise, he doesn't know the topic.
Constraints
2≤N≤500
1≤M≤500
Output Format
On the first line, print the maximum number of topics a 2-person team can know.
On the second line, print the number of 2-person teams that can know the maximum number of topics.
Sample Input
4 5
10101
11100
11010
00101
Sample Output
5
2
Explanation
(1, 3) and (3, 4) know all the 5 topics. So the maximal topics a 2-person team knows is 5, and only 2 teams can achieve this.
this is a a part of my work.Any clue how can i get this to work
#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
int main() {
int n, m, max = 0, max1 = 0, count = 0;
cin >> n >> m; //for input of N and M
int a[n][m];
for (int i = 0; i<n; i++) //for input of N integers of digit size M
for (int j = 0; j<m; j + >>
cin >> a[i][j];
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
max = 0;
for (int k = 0; k<m; k++)
{
if (a[i][k] == 1 || a[j][k] == 1) max++;
cout << k;
if (k = m - 1 && max>max1) max1 = max;
if (k == m - 1 && max == max1) count++;;
}
}
}
cout << max1 << endl << count;
return 0;
}
I think the way of taking my input logic is wrong.could you please help me out.I am stuck in this question from 5 days.
PLease only help me on how should i take input and how to read the digit of integer.
Don't have a compiler with me so there's probably a syntax boner or two in there, but the logic walks through on paper.
Builds the storage:
std::cin >> n >> m; //for input of N and M
std::vector<std::vector<bool>>list(n,std::vector<bool>(m, false));
Loads the storage:
char temp;
for (int i = 0; i < n; i++) //for input of N integers of digit size M
{
for (int j = 0; j < m; j++)
{
std::cin >> temp;
if (temp == 1)
{
list[i][j] = true;
}
}
}
Runs the algorithm
for (int a = 0; a < n; a++)
{
for (int b = a+1; b < n; b++)
{
int knowcount = 0;
for (int j = 0; j < m; j++)
{
if (list[a][j] | list[b][j])
{
knowcount ++;
}
}
if (knowcount > max)
{
groupcount = 1;
max = know;
}
else if(knowcount == max)
{
groupcount ++;
}
}
}
Your method of input is wrong. According to your method, the input will have to be given like this (with spaces between individual numbers):
1 0 1 0 1
1 1 1 0 0
1 1 0 1 0
0 0 1 0 1
Only then it makes sense to create a matrix. But since the format in the question does not contain any space between a number in the same row, thus this method will fail. Taking into consideration the test case, you might be tempted to store the 'N' numbers in a single dimensional integer array, but keep in mind the constraints ('M' can be as big as 500 and int or even unsigned long long int data type cannot store such a big number).

How to fill a 2D array with Every Possible Combination? C++ Logic

I can't figure out the logic behind this one... here's what I have so far:
#include <iostream>
using namespace std;
int thearray[4][4];
int NbPos = 4;
int main() {
int i2;
int q2;
for(int i = 1; i < 4; i++) {
for(int q = 1; q < 4; q++) {
for(int c = 0; c < NbPos; c++) {
thearray[i][q] = c;
}
}
}
}
This is filling the array up to the end is still:
3 3 3
3 3 3
3 3 3
but it's doing so without hitting anywhere near every possible combination.
Ideally once it gets to:
0 0 0
0 0 0
0 0 3
the next step SHOULD be:
0 0 0
0 0 0
0 1 0
so it hits a TON of combinations. Any ideas on how to make it hit them all? I'm stumped on the logic!
with the way you're iterating over this, a 1-dimensional array would make the looping simpler. you can still mentally treat it to have rows and columns, however they are just layed out end-to-end in the code.
you could try something like this; however if you want it in a 2D format specifically that challenge is left to you ;)
#include <iostream>
using namespace std;
#define rows 4
#define columns 4
int main() {
int thearray[rows * columns] = {0};
int NbPos = 4;
int lastPos = rows * columns - 1;
while (true) {
thearray[lastPos]++;
int pos = lastPos;
while (thearray[pos] == NbPos and pos >= 1) {
thearray[pos - 1]++;
thearray[pos] = 0;
pos--;
}
bool finished = true;
for (int i = 0; i < rows * columns; i++) {
if (thearray[i] != NbPos - 1) {
finished = false;
}
}
if (finished) {
break;
}
}
for (int i = 0; i < rows * columns; i++) {
std::cout << thearray[i] << " ";
if (i % rows == rows - 1) {
cout << endl; // makes it look like a 2D array
}
}
}
It makes sense to have the final form as all 3s , since you loop every element of the array and you assign it at the end with 3 .
So the next element will only take into account the combination with the final value of the previous element (which will be 3).
Thinking in math terms, your complexity is N^3 so to speak (actually is N^2 * 4 , but since your N is 3 ...).
Your approach is wrong, since you want to find permutations, which are defined by a factorial function , not a polinomial function.
The necessary complexity for the output doesn't match the complexity of your algorithm (your algorithm is incredbily fast for the amount of output needed).
What you are looking for is backtracking (backtacking will match the complexity needed for your output).
The recursion function should be something like this (thinking on a 1D array, with 9 elements):
RecursiveGeneratePermutations(int* curArray, int curIdx)
{
if (curIDX==9)
{
for (int i=0; i<9;i++)
{
// write the array
}
} else {
curArray[curIdx]=0;
RecursiveGeneratePermutations(curIdx+1);
curArray[curIdx]=1;
RecursiveGeneratePermutations(curIdx+1);
curArray[curIdx]=2;
RecursiveGeneratePermutations(curIdx+1);
curArray[curIdx]=3;
RecursiveGeneratePermutations(curIdx+1);
}
}
Now you only need to call the function for the index 0 :
RecursiveGeneratePermutations(arrayPtr,0);
Then wait...allot :).

Retrieval of items from a knapsack using dynamic programming

I'm new to dynamic programming and have tried my first DP problem. The problem statement is
Given a knapsack of size C, and n items of sizes s[] with values v[], maximize the capacity of the items which can be put in the knapsack. An item may be repeated any number of times. (Duplicate items are allowed).
Although I was able to formulate the recurrence relation and create the DP table, and eventually get the maximum value that can be put in the knapsack, I am not able to device a method to retrieve which values have to be selected to get the required sum.
Here is my solution:
#include <iostream>
#include <cstdlib>
#include <algorithm>
#include <vector>
using namespace std;
int main()
{
int s[] = { 1, 3, 4, 5, 2, 7, 8 , 10};
int v[] = { 34, 45, 23, 78, 33, 5, 7 , 1};
int n = ( (sizeof(s)) / (sizeof(s[0])) );
vector<int> backtrack;
int C = 15;
int pos;
int m[20];
m[0] = 0;
int mx = 0;
for ( int j = 1; j <= C; j++) {
mx = 0;
m[j] = m[j-1];
pos = j-1;
for ( int i = 0; i < n; i++) {
mx = m[i-s[i]] + v[i];
if ( mx > m[i] ) {
m[i] = mx;
pos = i - s[j];
}
}
backtrack.push_back(pos);
}
cout << m[C] << endl<<endl;
for ( int i = 0; i < backtrack.size(); i++) {
cout << s[backtrack[i]] <<endl;
}
return 0;
}
In my solution, I've attempted to store the positions of the maximum value item selcted in a vector, and eventually print them. However this does not seem to give me the correct solution.
Running the program produces:
79
2
3
0
5
2
7
8
10
34
45
23
78
33
5
7
It is obvious from the output that the numbers in the output cant be the sizes of the items selected as there there no item of size 0 as shown in the output.
I hope that you will help me find the error in my logic or implementation. Thanks.
You are following the greedy approach. It's pretty clever , but it is heuristic. I will not give you the correct code, as it might be a homework, but the recursive function knapsack would look like this:
knapsack(C): maximum profit achivable using a knapsack of Capacity C
knapsack(C) = max { knapsack(C-w[i]) + v[i] } for all w[i] <= C
knapsack(0) = 0
In code:
dp(0) = 0;
for i = 1 to C
dp(i) = -INF;
for k = i-1 downto 0
if w[k] < i then
dp(i) = max{dp(i-w[k]) + v[k], dp(i)};
print dp(Capacity);