C++ Code:
#include<iostream>
using namespace std;
int main()
{
int N;
cin>>N;
int *A = new int[N];
int i=0;
for(i=0;i<N;i++)
cin>>A[i];
while(cout<<A[--N]<<' ' and N);
delete[] A;
return 0;
}
Print the integers of the array in the reverse order in a single line separated by a space.
Does anyone know what is "and N" do in cout statement?
It's a cryptic way of writing:
while( (cout<<A[--N]<<' ') and (N != 0) );
// output is successful and N is not equal to zero.
It could be written more clearly as:
for ( ; N != 0; --N)
{
cout << A[N-1] << ' ';
}
Since it's theoretically possible for N to be negative, it will be better to use:
for ( ; N > 0; --N)
{
cout << A[N-1] << ' ';
}
N is an integer variable, value of type int can be implicitly converted to bool (non zero becomes true and zero becomes false). So the expression basically sais execute when result of operator<< converted to bool is true and N is not equal to zero. Logically this code
while(cout<<A[--N]<<' ' and N);
is equal to:
do {
bool b1 = cout<<A[--N]<<' ';
bool b2 = N;
} while( b1 and b2 );
actual code is a little different due to short circuit but that differences are unimportant in this case.
The part and N that can be also written like && N of the while statement
while(cout<<A[--N]<<' ' and N);
that as it has been pointed out can be rewritten like
while(cout<<A[--N]<<' ' && N != 0);
checks that N that is being decreased (A[--N]) in each iteration of the loop is not equal to 0.
So the loop outputs elements okf the array in the reverse order.
The word and is a so-called alternative token for the primary token &&.
It is just a way of writing the code by some programmers.
It is actually written as
while( (cout<<A[--N]<<' ') and (N != 0) );
Basically 'and' operator returns true when both operands are non zero values.
So cout will give number of characters it printed which will be non zero in this case and until the value of N becomes zero your loop will be execute.
Related
For clarification, let's consider the following program:
#include <iostream>
int main(void) {
short int i; // declaration
short int value;
short int sum;
i = value = sum = 0; // initialization
std::cout << "Enter a value: ";
std::cin >> value;
while (i != value) { // ### here's the confusion ###
sum += i;
i++;
}
std::cout << "Total sum: " << sum << std::endl;
return 0;
}
Look at the while (i != value), when this expression is given, the results shows Total sum: 45 whereas if we put while (i <= value), it shows Total sum: 55. (Input's given 10 for example)
Here, the confusion is, when should we use != and <= or >= operations in loops, any specific condition?
According to TutorialsPoint's Operators Reference
it tells that != (returns true used when two operands are unequal).
<= (returns true when used when we need to ensure if the first operand is lesser than or equal to second).
It was expected to get no difference in output, but something's misunderstood.
This while loop
while (i != value)
does not include the iteration when i is equal to value because in this case the condition i != value evaluates to false.
This while loop
while (i <= value)
includes the iteration when i is equal to value because in this case the condition i <= value evaluates to true.
In fact the first condition can be rewritten the following way (provided that initially i is less than value)
while ( i < value )
Now compare it with the condition in the second loop that in turn can be rewritten like
while ( i < value || i == value )
That is you have two different conditions.
With
while( i <= value)
the last iteration is with i == value. With
while ( i != value)
The body of the loop will not be executed when i == value. That is the reason you observe the difference.
This is a good chance to learn how to use a debugger. And/Or realize that your example is already too complicated to directly see what is going on. You would have spotted the difference more easily with
int i = 0;
int value = 5;
while ( i != value) {
std::cout << i << " ";
}
i = 0;
while ( i <= value) {
std::cout << i << " ";
}
Disclaimer: This question is more of a challenge, and the post is also quite long. Read only in free time!
The Problem:
Basically, suppose there is a single line of integer inputs:
32352\n // assuming single digits only and no spaces for simplification
We have to remove duplicates from the inputs, and then display them. So, output should be:
After removing duplicates: 2, 3, 5 // display them in any order
However, there is a catch:
Do not use any data structures containers.
Edit: I believe containers are what I meant (thanks Vlad!).
So, my question is: What is the error in my implementation, and is there another (better) way to do it?
My thought process:
Since we are not allowed use of any data structure, we cannot store the inputs (I think?).
However, since it is already stored in memory on input, that is not a problem.
More of a problem is removing the duplicates. We will have to manipulate the input stream.
The first thing that struck me is that we can sort the inputs. That is,
32352
becomes:
22335
And now, simply print the first element of each range.
Working on this idea, I came across the std::cin.get() and std::cin.putback() methods, both accepting a char.
I also realized I would have to use recursion.
And hence, the code becomes (I have used insertion sort):
The Code:
The sort() function is where the error is. It uses a running index ala arrays, and this is used to uniquely identify each element.
In each iteration, the index_of_element element is found and selected, and we determine where in the remaining (virtual) array, we need to place it. For example, if in our original input:
32352 // S = sorted subarray
SU--U // U = unsorted subarray
, the first 2 is selected, we "shift" 3 (as 3 < 2).
Now, there are no more elements left to shift, we "place" 2.
The result should become:
23352
SSU-U
The (buggy) implementation:
bool sort(int index_of_element, int index = 0, char prev_element = 0)
{
static char element;
char digit;
// retrieve an element from memory
std::cin.get(digit);
// If not end of input
if(digit != '\n')
{
// store the element for comparision
if(index == index_of_element)
{
element = digit;
}
// continue forward until '\n'
bool result = sort(index_of_element, index + 1, digit);
// if we are in sorted subarray
if(index <= index_of_element)
{
// If element belongs here(also if this is first element(prev_element is 0)), place it
if(element > prev_element)
{
digit = element;
// Signal that element has been placed
element = 0;
}
// Else, if element not already placed, we need to shift elements
else if(element != 0)
{
// Place the previous element here
digit = prev_element;
}
}
// Put it back in memory
std::cin.putback(digit);
// And return the result
return result;
}
// Which is generated here when end of input is reached
else
{
// If sorted all elements, break loop
if(index_of_element == index)
{
return false;
}
// Else, continue sorting
else
{
return true;
}
}
}
(A wall of code, but I didn't want to skip anything relevant), and it should be used as:
...
int index_of_element = 0;
while(sort(index_of_element++));
...
The display function is ready, and it works properly.
What I do know is that it gets stuck in an infinite loop and the values are lost.
What is going wrong?
And should I add the output (The post is already very long)?
The problem seems to be that you don't put the newline back into the stream, while your code assumes that it will be there.
That is, after your first pass, digit != '\n' is always true.
Put the newline back into the stream, or break when you've reached the true end-of-stream.
(There could also be problems with (ab)using std::cin like this, but I'm not sure, and that's another matter anyway.)
You can do it with only function objects, in a single pass.
#include <iostream>
#include <sstream>
#include <functional>
void print_unique_ints(std::istream & in, std::ostream & out, std::function<bool(int)> unseen) {
for (int i; in >> i;) {
if (unseen(i)) {
out << i << ' ';
print_unique_ints(in, out, [&](int j){ return (i != j) && unseen(j); });
return; // not actually needed, previous call only ends when input is exhausted
}
}
}
int main() {
print_unique_ints(std::cin, std::cout, [](int){ return true; });
}
See it live
Each call to print_unique_ints skips previously seen ints, prints the unseen int, and adds to the filter
Substituting values for variables; and function calls for expressions; in the first call
for (int i; in >> i;) { // i = 3
if (true) {
out << 3 << ' ';
print_unique_ints(...) // see below
}
}
The second
for (int i; in >> i;) { // i = 2
if ((3 != i) && true) {
out << 2 << ' ';
print_unique_ints(...) // see below
}
}
The third
for (int i; in >> i;) { // i = 3, 5
if ((2 != i) && (3 != i) && true) { // skips over the 3
out << 5 << ' ';
print_unique_ints(...) // see below
}
}
The forth
for (int i; in >> i;) { // i = 2
if ((5 != i) && (2 != i) && (3 != i) && true) { // skips the 2 and finds the end of input
}
}
Note that && true never changes the result in the if
A variation of bitset (or mask) implem...using the commutative property of multiplication
Take a function f which maps every digit to a unique prime p_i
0 1 2 3 4 5 6 7 8 9
2,3,5,7,9,11,13,17,19,23
If all numbers are found the total amount to N=2*3*5*7*9*11*13*17*19*23=2007835830
Consume cin as c, if f(c) divides N, print c and update N /= f(c)
#include <iostream>
#include <sstream>
int f(char c){
if(c=='0') return 2;
if(c=='1') return 3;
if(c=='2') return 5;
if(c=='3') return 7;
if(c=='4') return 9;
if(c=='5') return 11;
if(c=='6') return 13;
if(c=='7') return 17;
if(c=='8') return 19;
if(c=='9') return 23;
}
int main() {
std::istringstream in("2 2 2 3 5");
int N = 2007835830;
char c;
while(in >> c){
if(c=='\n') break;
int p_i = f(c);
if(N % p_i == 0){
N = N/p_i;
std::cout<<c<<" ";
}
}
}
I am sure that this phrase
Remove duplicates from input without use of any data structures
means that you shall not use any container like for example std::string or an ordinary array.
The assignment is not simple for a beginner.
Here are my five cents.
#include <iostream>
#include <type_traits>
template <typename T>
T remove_duplicates( T n )
{
static_assert ( std::is_integral<T>::value );
const T Base = 10;
T result = n % Base;
for ( T multiplier = 1; n /= Base; )
{
T digit = n % Base;
T tmp = result;
bool unique = true;
while ( ( unique = tmp % Base != digit ) && ( tmp /= Base ) );
if ( unique )
{
multiplier *= Base;
result = digit == 0 ? result * multiplier + digit
: digit * multiplier + result;
}
}
return result;
}
int main()
{
for ( int n : { 0, 1, 10, 101, 100, 10203, -1, -10, -101, -100, - 10203 } )
{
std::cout << n << ": " << remove_duplicates( n ) << '\n';
}
return 0;
}
The program output is
0: 0
1: 1
10: 10
101: 10
100: 10
10203: 1230
-1: -1
-10: -10
-101: -10
-100: -10
-10203: -1230
That is you are building a new number from the source number by checking whether the new number already contains a digit from the source number.
The function can work with any integer type signed or unsigned. It correctly processes digits equal to 0.
It was said not to use any arrays, vectors, stacks, queues etc and neither our own implementations of it. I simplified the condition.
Well I've got bad news for you; this is not possible.
Given an input of length N you will need to somehow remember the previous N - 1 values to decide whether to print the Nth value or not. This is not possible with constant space.
So you need some data structure.
Now ...
Since we are not allowed use of any data structure, we cannot store the inputs (I think?).
However, since it is already stored in memory on input, that is not a problem.
So let's assume the existence of a (mutable) array of length N, containing the input values. Now we can solve this without using additional storage / data structures:
Select some value as special value
Iterate over the numbers until you find a value which is not that special value. print that value. Write the special value to the array where you found the value you just printed. finish iterating over the numbers, overwritte each occurrence of the just printed value with the special value.
repeat (from 2) until the input consists only of special values.
You just need to think about a way to handle the case where the special value was present in the input from the start.
Below are my codes:
char str [80];
int n;
n = MAX + ( rand () % 1000 + 1);
cout << "number: " << n << endl;
constructArray(str, n);
void constructArray (char str [], int n)
{
for (int i = 0; i < n; i++)
{
while (n > 0)
{
// get last pair of digits
str [i] = n%10;
n/= 10;
}
cout << str[i] << endl;
}
}
I can't figure out why my compiler doesnt output any values.
It works if I didnt implement array.
Any help will be appreciated.
In the first iteration of your for loop, when while is executed for the first time (i=0), n will be reduced to 0. Thus your for loop will execute only once. This will lead to only str[0] being set. Others already pointed out that char cant store large numbers, but this is differnt problem.
There are few problems with you code.
You are storing integer in char type array.
for loop will only be executed only once because while loop make n = 0.
hence only str[0] will be assigned.
In the while loop,the n is still divided by 10 until n is reduced to 0. Then the for loop will finished. So only output str[0].
I expect "match!" when the n2 tail is the same that the n1 tail, otherwise, "do not match!".
Example of "match!": n1 = 123456 and n2 = 3456.
The problem is when I enter, for example, n1 = "45" and n2 = "645". It should not match, but the output is "match!".
bool different_tail = false;
char n1[11], n2[11];
cin >> n1 >> n2;
for(int i = strlen(n1)-strlen(n2); i < strlen(n1); i++){
if(i < 0 || n1[i] != n2[i-(strlen(n1)-strlen(n2))]){
different_tail = true;
break;
}
}
if(different_tail)
cout << "does not match!" << endl;
else
cout << "match!" << endl;
I don't want to use other ways to solve the problem (like, strcmp, etc...), I want to understand what's happening.
What happens is that with n1 being 45 and n2 being 645, the loop variable i will start at -1, i.e. it is negative.
However, strlen yields an unsigned value (a value of type size_t). When comparing a signed with an unsigned value (as you do in the expression i < strlen(n1)), the signed value is converted to an unsigned value. Since it's negative, this causes an underflow, so i is a very large value -- larger than strlen(n1).
You can observe the same effect with e.g.
int i = -1;
size_t x = 5;
if (i < x) {
cout << "yes\n";
} else {
cout << "no\n";
}
This program prints no.
You can avoid your issue by casting the return value of strlen, i.e. change your loop condition to
i < static_cast<int>(strlen(n1))
This question (and the accompanying answers) provide a more in-depth discussion of this topic.
Look at this line:
for(int i = strlen(n1)-strlen(n2); i < strlen(n1); i++){
here i is an int whereas strlen(n1) is an size_t(an unsigned integer type). Performing "less than" operator between signed and unsigned type will convert all operands to unsigned types, in this case unsigned(i) becomes a very large integer, so the for loop is never executed.
BTW, it's not a good practice to use strlen in for loop, since strlen is an expensive function and will be called at every iteration. You can store strlen result in an variable and use the variable instead.
#include <iostream>
#include <string>
#include <algorithm>
#include <cstdlib>
#include <cstdio>
using namespace std;
static bool isanagram(string a, string b);
int main(void)
{
int i,n,j,s;
cin >> n;
string a, b;
cin >> a >> b;
if(!isanagram(a,b)) cout << "False" << endl;
else cout << "True" << endl;
return 0;
}
static bool isanagram(string a, string b)
{
int i, j, size, s=0;
size = a.size();
bool k;
for(i=0;i<size;i++)
{
k=false;
for(j=0;j<size;j++)
{
if(a[i] == b[j]) { k = true; break; }
}
if(k==true) s+=1;
}
cout << a[2] << b[2] << endl;
if(s == size) return true;
else return false;
}
I don't know where exactly is the problem so i just pasted the whole code.
It should be a simple program capable for finding if two strings are anagrams, but it's not working and i don't know why. I used pointers in the program so thought the might be the problem and removed them, i removed other things additionally but still it's not working. If you can give it a look-see and tell me some idea where i might've gone wrong with my code ?
Thank you in advance.
The logic for your isanagram function is fatally flawed - it will never work correctly, even if you manage to fix the bugs in it.
You need to make sure that you have a correct algorithm before you start coding. One simple algorithm might be:
sort a
sort b
isanagram = (a == b)
It's not always return true:
Here's my input:
0
sdf
fda
Here's output I got:
fa
False
Regarding your task: if performance is not an issue for you task, just sort 2 strings (using std::sort) and compare results.
Regarding your style:
use string::length() instead of size() -- it's more idiomatic
instead of if(s == size) return true; else return false; consider return s == size
pass your strings by const reference, not by value
consider declaring variables as close to point of their usage as possible (but not closely) and initialize them when declaring (i, j, k, size all fit this hint)
Your approach is fine but it has a small flaw. You ensuring that every char from string a is present in string. So if a = "aab" and b = "abc", your approach will flag them as anagram. You also need to take the count of char in account.
The definition of anagram is:
An anagram is a type of word play, the result of rearranging the letters of a word or phrase to produce a new word or phrase, using all the original letters exactly once;
Easiest way as many have suggested is to ensure that the strings are of the same length . If they are, sort the two string and check for equality.
If you want to patch your approach, you can make the char in string b NULL after it has been matched with a char in string a.
Something like:
if(a[i] == b[j]) { b[j] = 0; k = true; break; }
in place of your:
if(a[i] == b[j]) { k = true; break; }
This way once a char of b has been matched it cannot participate again.
There are essentially two ways of checking for anagrams:
Sort both strings and see if they match. If they are anagrams, they will both have the same letters and a sort would order them into the same sequence.
Count the frequency of each char in each string. If they are anagrams, the frequency counts for each char will be the same for both strings.
First things first: don't declare the method static. It's a confusing keyword at the best of times given all the roles it can fulfill... so reserve for times when you really have to (method or attribute of a class that is not tied to any instance for example).
Regarding the algorithm: you're nearly there, but presence only is not sufficient, you need to take the number of characters in account too.
Let's do it simply:
bool anagram(std::string const& lhs, std::string const& rhs)
{
if (lhs.size() != rhs.size()) return false; // does not cost much...
std::vector<int> count(256, 0); // count of characters
for (size_t i = 0, max = lhs.size(); i != max; ++i)
{
++count[lhs[i]];
--count[rhs[i]];
}
for (size_t i = 0, max = count.size(); i != max; ++i)
if (count[i] != 0) return false;
return true;
} // anagram
Let's see it at work: anagram("abc","cab")
Initialization: count = [0, 0, ...., 0]
First loop i == 0 > ['a': 1, 'c': -1]
First loop i == 1 > ['a': 0, 'b': 1, 'c': -1]
First loop i == 2 > ['a': 0, 'b': 0, 'c': 0 ]
And the second loop will pass without any problem.
Variants include maintaining 2 counts arrays (one for each strings) and then comparing them. It's slightly less efficient... does not really matter though.
int main(int argc, char* argv[])
{
if (argc != 3) std::cout << "Usage: Program Word1 Word2" << std::endl;
else std::cout << argv[1] << " and " << argv[2] << " are "
<< (anagram(argv[1], argv[2]) ? "" : "not ")
<< "anagrams" << std::endl;
}
I see some problems with your code. Basically the algorithm is wrong. It will match characters within a.size(). It takes no account for duplicates (in either a or b).
Essentially, you should sort the strings and then compare for equality.
If you can't sort, at least remove the b characters from the comparison, eliminate the k variable.