Help me understand this algorithm (simple) - c++

I have just made a queue class and I now have to use it to do this.
Write a c++ program to generate all strings using A,B,and C as the letters.
The strings must be generated in the following order:
A
B
C
AA
AB
AC
BA
BB
BC
CA
CB
CC
AAA
AAB
AAC
ABA
ABB
ABC
ACA
ACB
ACC
etc.
It's supposed to do this until my queue overflows.
Now, I simply don't understand the algorithm the teacher suggested using, which is this.
Start with A and B and C in the queue.
“Remove it Display it then Add Add Add ”
The add add add thing throws me off, how does it accomplish getting these letters in this particular order?

I think your teacher meant "Add A, Add B, Add C".
Suppose you have A, B and C in the queue. You pop the first one off the queue and print it. This should print A. Then you add an A to that. This gives you AA, which you push back into the queue. You also add a B and add a C to the string you popped last (giving you AB and AC) and push them back into the queue as well. Now your queue contains [B,C,AA,AB,AC]. Next you will pop B and do the same sequence of operations on that as well, and so on until you run out of space in your stack.

Let our behavior be:
For any token X, add XA, XB, and XC to the queue.
Our flow will be something like:
Start with a Queue
A B C
Pop (and display) off A
B C
Behave on token: "A"
add AA
add AB
add AC
B C AA AB AC
Pop (and display) off B
C AA AB AC
add BA
add BB
add BC
C AA AB AC BA BB BC
If we pretend our function is
main() {
Queue q;
q.add("A");
q.add("B");
q.add("C");
while(true) {
process(q.pop());
}
}
process(String x, Queue q) {
display x;
q.add(x + "A");
q.add(x + "B");
q.add(x + "C");
}
Get it now?

A B C
prints A
new queue state
B C A A A
prints B
new queue state
C A A A B B B
prints C
new queue state
A A A B B B C C C
prints A
new queue state
A A B B B C C C A A A
prints A
new queue state
A B B B C C C A A A A A A
prints A
new queue state
B B B C C C A A A A A A A A A
This was my first interpretation of the cycle, but i must be getting it wrong, because i go from 1 repeat to 3 right away.
Update: definitely read the initial problem wrong after seeing the other responses.

Related

Establishing a connection between data given using istringstream and struct/vector

I have the following data in a file, let the columns be [A B C D E]:
a1 b1 c1 d1 e1
a2 b2 c2 d2 e2
a3 b3 c3 d3 e3
.....
All are integers. A is just the serial number. let B be a node having only max of 4 terminals. C represents which terminal of B is taken. Similarly, D is a node having max of 4 terminals and E represents the terminal of D choosen. example: c1 of b1 is connected to e2 of d2.
I have successfully read the data from the files line by line using istringstream and getline as below:
while (getline(infile, line))
{
int i=0;
istringstream iss(line); // string stream
while(getline(iss, temp[i]))
{
cout<< temp[i] << endl;
++i;
};
}
I am not able to conclude on how to save the connections mentions above line to line. I am new to c++ and would appreciate any ideas and implementation. Thanks!
you can just declare a vector<vector<int>> nameVector,(give it a size) and inside of while you put the data. Or be more specific on what you want.

How can I search through a 2D array to make sure that the there are not more than 3 consecutive chars?

I have a 2D array of 3 random chars, a, b, and c. I need to make sure that no column or row has three or more repeating chars.
I'm not really sure how to check the arrays. I think I need to use a loop to go through the array but I'm not sure how to check if there are repeats. To clarify,
if a column has three A's in a row that would not be allowed or could 3 B's be in a column, etc.
So if it is like AAA in 3 consecutive array index (in terms of rows and columns), it should stop.
You need to use for loops if you know the indexes of your array.
so lets say:
char[][] arr= new char[20][20];
for(int i=0; i<18;i++){
for(int j=0; j<18;j++){
if( arr[i][j] ==arr[i][j+1] && arr[i][j] == arr[i][j+2]))
{
break;//mark it as Duplicate
}
else if (arr[i][j] == arr[i+1][j] && arr[i][j] == arr[i+2][j])
{
break;//mark it as Duplicate
}
else
continue;
}
}
So basically you are traversing the array and comparing 3 consecutive elements together. if they are equal it breaks.
You can use an automaton. One to recognize sequences of AAA, BBB and CCC is:
state input next stop
===== ===== ==== ====
0 A a1 no
0 B b1 no
0 C c1 no
a1 A a2 no
a1 B b1 no
a1 C c1 no
b1 A a1 no
b1 B b2 no
b1 C c1 no
c1 A a1 no
c1 B b1 no
c1 C c2 no
a2 A 3 yes
a2 B b1 no
a2 C c1 no
b2 A a1 no
b2 B 3 yes
b2 C c1 no
c2 A a1 no
c2 B b1 no
c2 C 3 yes
3 A 3 yes
3 B 3 yes
3 C 3 yes
you can run this automaton for each row and for each column and stop as soon as you get output yes (it has detected three consecutive letters) You'll get stopped as soon as you recognize the first occurrence of three consecutive letters with only two passes (one for the rows, other for the columns) through the matrix. Of course, initial state is 0.

Why this Array is assigning to non specified array?

/* what i observed is :
when i give string like "ab" to b(array)
then the output is : "ab" "help" "dude"
when i give "abc"
then output is : "abc" " " "dude"
if i give "abcd"
then output is : "abc" "d" "dude"
so on */
#include<stdio.h>
main()
{
char a[5]="help",b[3],c[10]="dude";
scanf("%s",b);
printf("\t%s",b);
printf("\t%s",a);
printf("\t%s",c);
}
/* what i dont get is :
Here iam gaving a string to b(array), why, if the string has more than the
required no. of charecters, its printing those charecters in other arrays
(though i had not assiged scanf to other arrays )?
Remember that a string in C needs space for a null terminator. If there is no space, printing will continue "to the next nul". Here is how your memory looks at initialization:
h e l p \0 \0 \0 \0 d u d e \0
^ ^ ^
a b c
When you read in a string ab in the location pointed to by b:
h e l p \0 a b \0 d u d e \0
^ ^ ^
a b c
And all is well. But abc gives:
h e l p \0 a b c \0 u d e \0
^ ^ ^
a b c
and when you print b you will get abc; printing c will get you nothing (first character is '\0').
Finally, with an input of abcd you get
h e l p \0 a b c d \0 d e \0
^ ^ ^
a b c
And printing c will result in "d" - exactly as you are seeing.
In fact, the order in which things are stored in memory is not "defined", although usually the compiler will do something similar to the above. So while you know that you can't write to memory that isn't yours, you can't be sure what will happen when you do (as in your case). That is why it is called "undefined behavior". You can't rely on other compilers giving you the same result - or even the same compiler giving you the same result...
Make sense?
The solution, of course, is to allocate more space to b. That would result in more '\0' between b and c, and nothing gets overwritten.
edit - I did just realize that it seems that the order in which b and a are stored is backwards from how I just described it - because it's a, not c that is getting overwritten. Which shows that the compiler orders things as it jolly well pleases, and that I ought to wear my glasses when I write detailed answers. But the principle is exactly the same - so I will "leave the rest as an exercise for the student".
Your arrays are placed in memory in the following order
c[10], b[3], a[5]
So if array b will contain more characters than it can accomodate then some its characters will overlap array a,
Consider these two arrays, b and a, as they are in memory
b[0] b[1] b[2] a[0] a[1] a[2] a[3] a[4]
When you eneters "abc" in b you got
b[0] b[1] b[2] a[0] a[1] a[2] a[3] a[4]
'a' 'b' 'c' '\0' 'e' 'l' 'p' '\0'
So after executing the statements
printf("\t%s",b);
printf("\t%s",a);
the output is
"abc" ""
because a[0] contains '\0'
When you entered "abcd" you got
b[0] b[1] b[2] a[0] a[1] a[2] a[3] a[4]
'a' 'b' 'c' 'd' '\0' 'l' 'p' '\0'
and the output is
"abcd" "d"
because a[0] contains 'd' and a[1] contains '\0'
b[3] is an array of 3 characters. However the string abc is made of 4 characters, the last one being \0, indicating end of the string. So if you want be to be able to store abc, you need to declare at least an array of 4 characters, not 3
when you give abc as input your array b gets filled up(as it has only 3 places ) and has no space left for \0character. As a result when you try to print it out as a string .. it overflows and causes the error
For a string to be printable, it has to be of the following format:
stringtext\0 but when you use up all the spaces in your array b you leave no space for \0 as a result when you print it , there is error
Also this statement is wrong in your code :
scanf("%s",&b);
it should be :
scanf("%s",b);
So what's really happening is you are going outside the end of your arrays and overwriting memory.
When you provide 'ab' as input to b, it works because b is large enough to store 'ab' and the \0 as others have mentioned.
When you provided 'abc' as input, b does not have enough space allocated to store abc and the null so it only stores 'abc' and then the null appears to get written to the first byte of the a array, which means it's just an empty string... or maybe it doesn't, this is the undefined part. Who knows what is stored outside your array. It just so happens you are probably getting lucky since those arrays you have defined are most likely in contiguous memory.
When you provide 'abcd' as input, the d and the null get written to the a array.
Many times in less-simple programs, you'll get a SEGV with programming errors like this.
This is simply one of the case of undefined behavior. b[3] can store a string of three characters (including \0), but when your input is abc it is of four character string and you can't store it in array b. You will get anything.
When you place "abc" into b[3], it's going past the end of the array. The abc string is four bytes since it has a nul terminator at the end.
Since it's undefined behaviour, anything can technically happen but what's actually happening is that the nul at the end of the string is overwriting the first character of the next variable in memory, rendering it an empty string.
Quickest solution is to ensure your character array are big enough to store all the characters plus the terminator:
char b[4] = "abc";
Or let the compiler handle it for this particular simple case:
char b[] = "abc";

Advice for POUR1 on SPOJ?

I need help with this problem POUR1. I think
it can be solved with bruteforce approach, but I read that it is a graph problem (BFS). I solved problems like ABCPATH, LABYR1, PT07Y, PT07Z, BITMAP, ...
But I don't know how to approach POUR1 in BFS manner.
Can someone give me some advice?
Problem statement:
Given two vessels, one of which can accommodate a litres of water and the other - b litres of water, determine the number of steps required to obtain exactly c litres of water in one of the vessels.
At the beginning both vessels are empty. The following operations are counted as 'steps':
emptying a vessel,
filling a vessel,
pouring water from one vessel to the other, without spilling, until one of the vessels is either full or empty.
Input:
An integer t, 1<=t<=100, denoting the number of testcases, followed by t sets of input data, each consisting of three positive integers a, b, c, not larger than 40000, given in separate lines.
Output:
For each set of input data, output the minimum number of steps required to obtain c litres, or -1 if this is impossible.
Example:
Sample input:
2
5
2
3
2
3
4
Sample output:
2
-1
This question has a simpler solution. No need for BFS. Ad-hoc would do good.
method 1 - fill A, empty it into B. whenever A becomes empty fill it back, whenever B becomes full empty it. (all the above-mentioned actions count as individual moves). Continue this process until you arrive at the required amount of water in any one of the vessels. Get the number of moves here. (say C1).
method 2 - fill B, empty it into A. whenever B becomes empty fill it back, whenever A becomes full empty it. Continue this until you arrive at the required amount. Get the number of moves say C2).
The answer is min(C1,C2).
Source code in C++:
#include < cstdio >
#include < algorithm >
using namespace std;
int pour(int A, int B, int C) {
int move = 1, a = A, b = 0, tfr;
while (a != C && b != C) {
tfr = min(a, B - b);
b += tfr;
a -= tfr;
move++;
if (a == C || b == C)
break;
if (a == 0) {
a = A;
move++;
}
if (b == B) {
b = 0;
move++;
}
}
return move;
}
/** Reason for calculating GCD of a,b is to check whether an integral solution of
* equation of form ax + by = c exist or not, to dig deeper read Diophantine Equations
*/
int gcd(int a, int b) {
if (b == 0)
return a;
return gcd(b, a % b);
}
int main() {
int t, a, b, c;
scanf("%d", & t);
while (t--) {
scanf("%d%d%d", & a, & b, & c);
if (c > a && c > b)
printf("-1\n");
else if (c % gcd(a, b) != 0)
printf("-1\n");
else if (c == a || c == b)
printf("1\n");
else
printf("%d\n", min(pour(a, b, c), pour(b, a, c)));
}
return 0;
}
Consider the set of all a priori possibles states (eg [3, 7] meaning Vessel1 contains 3 litters and vessel2 contains 7 litters). You have a directed graph whose vertices are those states and whose edges are the possible moves. The question is to find a path in the graph joining the state [0, 0] to either a state of type [c, ?] or a state of type [?, c]. Such a path is typically searched by a BFS.

Cannot understand comma expression

#include <iostream>
using namespace std;
int main()
{
int a, b, c, max;
cout<<"a="; cin>>a;
cout<<"b="; cin>>b;
cout<<"c="; cin>>c;
a>b?(max=a, a=b, b=max):a;
b>c?(max=b, b=c, c=max):a;
a>b?(max=a, a=b, b=max):a;
cout<<a<<" "<<b<<" "<<c;
}
This is a code where you can input 3 random numbers and it will put them in order. I don't understand this part, however:
a>b?(max=a, a=b, b=max):a;
b>c?(max=b, b=c, c=max):a;
a>b?(max=a, a=b, b=max):a;
How does it work, and why?
Let's say a = 6, b = 54, and c = 12.
a>b?(max=a, a=b, b=max):a; <-- sets max to 6, then a to 54, then 54=max. then compares 6 to 54 which is false and writes a (6) as the first number?
b>c?(max=b, b=c, c=max):a; <-- sets max to 54, b=12, 12=max. then compares 54 to 12 which is true in our case and writes c=12 as the second number?
a>b?(max=a, a=b, b=max):a; <-- sets max to 6, a=54, 54=max. then compares 6 to 54 which is false and writes 6 again, wtf?
The program itself works correctly. I just don't understand how the algorithm works.
This:
cond ? A : B
is roughly equivalent to this:
if (cond) {
A;
} else {
B;
}
This:
(X, Y, Z)
is roughly equivalent to this:
X;
Y;
Z;
i.e. each expression is evaluated completely, in turn.
Using these two rules, you should be able to trace the execution of your code. However, that code is grotesque, and should never have been written like that. So my recommendation is to just ignore it, and write the algorithm properly.
All the code's doing is abusing the comma operator's ability to do multiple things in one to swap values in one statement.
The first line finds the max of the first two numbers. The second finds the max of that and the third, so that it's now found the largest of the three. The third line sorts the other two in order afterwards.
It's about the same as this:
if (a > b)
swap (a, b); //b is max(a,b)
if (b > c)
swap (b, c); //c is max(max(a,b),c), which is largest
if (a > b)
swap (a, b); //b is max (a, b), so numbers are in order smallest to largest
a>b?(max=a, a=b, b=max):a
The final ":a" really doesn't do anything, it could just as easily have been ":0". It is essentially the statement that is to be carried out if the "a>b" is false. but since the a isn't assigned to anything, it doesn't do anything. so in this case
if(a > b){
max = a;
a = b;
b = max;
}
It uses the max variable to swap a and b; The SAME algorithm is used for the following two lines. So essentially
if a > b then swap them
now if b (which could hold a) > c then swap them
now if a (which could hold the older b) > b(which could hold the oldest c) then swap
Well, essentially I this is what happens.
a>b?(max=a, a=b, b=max):a;
the first section is just a normal comparison in the fashion of a tertiary if statement, so basically it checks if a>b, then ? is just equal to the first brackets set, so if its true, it evaluates the first section otherwise then the code after : is just like else and that is is evaluated.. The (max=a, a=b, b=max) basically evaluates each item in turn, so first max is set to a, then a = b and finally b = max; Same for the other two lines.
You can read more here: http://www.cplusplus.com/doc/tutorial/operators/
Hope this helped.