I have a given code from school, I need this as my output:
Digital Binair
0 is 000,
1 is 001,
2 is 010,
3 is 011,
4 is 100,
5 is 101,
6 is 110,
7 is 111
(3 bits)
I need to work with for loops, this is the given code:
#include <stdio.h>
#include <string.h>
#define ZERO '0'
#define ONE '1'
int main(void)
{
char rij[8][4];
int n, m;
strcpy( rij[0], "000" );
printf( "%s\n", rij[0] );
for ( n=1; n<8; n++ )
{
strcpy( rij[n], rij[n-1] );
printf( "%s\n", rij[n] );
// *ONLY ABLE TO TYPE IN HERE !!!! THE REST IS GIVEN !!!!*
}
for( n=0; n<8; n++ )
{
printf( "%i %s\n", n, rij[n] );
}
return 0;
}
I'm stuck at is how do I make a for loop that is working with bits. So lets say for(n = 0; n < 8; n++) how do I make the loop go form 000 to 001 to 010.
While there are many ways of generating a binary sequence, here the task appears to have been deliberately complicated (or made interesting) by the constraint that you modify code only at the location indicated and the initialisation of each successive string with the content of the previous one.
The arrays serve no purpose other than to make you think - it is a purely academic exercise, not a practical application. Each string is initialised with the content of the previous string (which the code you must add will have modified), the intent of the exercise is that you perform a binary "add 1" at each iteration.
To do that, starting from the LSB (rij[n][2]), if the digit is ZERO you set it to ONE, then move to the next n, else you set it to ZERO, and "carry" one, repeating the above process for the next most significant bit in the string n.
You can do that in a loop from the LSB (2) index to the MSB (0) index, and exiting the loop (break) when you set any bit to ONE.
Or for just three digits you can unroll-the loop thus:
if( rij[n][2] == ZERO )
{
rij[n][2] = ONE ;
}
else
{
rij[n][2] = ZERO ;
if( ... // test next bit [1] - enough of a hint I think.
Related
I recently had an interview question where I had to write a function that takes two strings, and it would return 1 if they are anagrams of each other or else return 0. To simplify things, both strings are of the same length, non-empty, and only contain lower-case alphabetical and numeric characters.
What I implemented a function that accumulates the XOR value of each character of each string independently then compared the final XOR values of each string to see if they are equal. If they are, I would return 1, else return 0.
My function:
int isAnagram(char* str1, char* str2){
int xor_acc_1 = 0;
int xor_acc_2 = 0;
for(int i = 0; i<strlen(str1); i++){
xor_acc_1 ^= str1[i] - '0';
xor_acc_2 ^= str2[i] - '0';
}
return xor_acc_1 == xor_acc_2;
}
My function worked for every case except for one test case.
char* str1 = "123";
char* str2 = "303";
To my surprise, even though these two strings are not anagrams of each other, they both returned 48 as their XOR value.
My question is: Can this be resolve still with XOR in linear time, without the usage of a data structure e.g. a Map, through modification on the mathematics behind XOR?
A pure xor solution will not work as there is information lost during the process (this problem is likely to exist in other forms of lossy calculation as well, such as hashing). The information lost in this case is the actual characters being used for comparison.
By way of example, consider the two strings ae and bf (in ASCII):
a: 0110 0001 b: 0110 0010
e: 0110 0101 f: 0110 0110
---- ---- ---- ----
xor: 0000 0100 0000 0100
You can see that the result of the xor is identical for both string despite the fact they are totally different.
This may become even more obvious once you realise that any value xor-ed with itself is zero, meaning that all strings like aa, bb, cc, xx, and so on, would be considered anagrams under your scheme.
So, now you've established that method as unsuitable, there are a couple of options that spring to mind.
The first is to simply sort both strings and compare them. Once sorted, they will be identical on a character-by-character basis. This will work but it's unlikely to deliver your requested O(n) time complexity since you'll almost certainly be using a comparison style sort.
The second still allows you to meet that requirement by using the usual "trick" of trading space for time. You simply set up a count of each character (all initially zero) then, for each character in the first string, increase its count.
After that, for each character in the second string, decrease its count.
That's linear time complexity and the strings can be deemed to be anagrams if every character count is set to zero after the process. Any non-zero count will only be there if a character occurred more times in one string than the other.
This is effectively a counting sort, a non-comparison sort meaning it's not subject to the normal minimum O(n log n) time complexity for those sorts.
The pseudo-code for such a beast would be:
def isAnagram(str1, str2):
if len(str1) != len(str2): # Can also handle different lengths.
return false
dim count[0..255] = {0} # Init all counts to zero.
for each code in str1: # Increase for each char in string 1.
count[code]++
for each code in str2: # Decrease for each char in string 2.
count[code]--
for each code in 0..255:
if count[code] != 0: # Any non-zero means non-anagram.
return false
return true # All zero means anagram.
Here, by the way, is a complete C test program which illustrates this concept, able to handle 8-bit character widths though more widths can be added with a simple change to the #if section:
#include <stdio.h>
#include <string.h>
#include <limits.h>
#include <stdbool.h>
#if CHAR_BIT == 8
#define ARRSZ 256
#else
#error Need to adjust for unexpected CHAR_BIT.
#endif
static bool isAnagram(unsigned char *str1, unsigned char *str2) {
// Ensure strings are same size.
size_t len = strlen(str1);
if (len != strlen(str2))
return false;
// Initialise all counts to zero.
int count[ARRSZ];
for (size_t i = 0; i < sizeof(count) / sizeof(*count); ++i)
count[i] = 0;
// Increment for string 1, decrement for string 2.
for (size_t i = 0; i < len; ++i) {
count[str1[i]]++;
count[str2[i]]--;
}
// Any count non-zero means non-anagram.
for (size_t i = 0; i < sizeof(count) / sizeof(*count); ++i)
if (count[i] != 0)
return false;
// All counts zero means anagram.
return true;
}
int main(int argc, char *argv[]) {
if ((argc - 1) % 2 != 0) {
puts("Usage: check_anagrams [<string1> <string2>] ...");
return 1;
}
for (size_t i = 1; i < argc; i += 2) {
printf("%s: '%s' '%s'\n",
isAnagram(argv[i], argv[i + 1]) ? "Yes" : " No",
argv[i], argv[i + 1]);
}
return 0;
}
Running this on some suitable test data shows it in action:
pax$ ./check_anagrams ' paxdiablo ' 'a plaid box' paxdiablo PaxDiablo \
one two aa bb aa aa '' '' paxdiablo pax.diablo
Yes: ' paxdiablo ' 'a plaid box'
No: 'paxdiablo' 'PaxDiablo'
No: 'one' 'two'
No: 'aa' 'bb'
Yes: 'aa' 'aa'
Yes: '' ''
No: 'paxdiablo' 'pax.diablo'
Why do you need to do XOR on the first place?
The most simple and fast enough approach is sort both the string by character and compare if both of them are equal or not. In this case, if you need faster sorting algorithm, you can use counting sort to achieve linear time.
Another way is, you can simply count the number of characters in each string and check if those counts are equal.
EDIT
Your XOR based solution is not right in terms of correctness. There can be more than one combination of characters which can XOR up to a same number, the XOR of characters/ASCII codes of two different strings might not yield to different XOR all the time. So for same string, the output will be always correct. But for different string, the output MAY not be correct always (False positive).
so I am trying to make a matrix reader that will take a text file that contains only data for a NxN matrix such as:
10 9 8 7
6 5 4 3
2 1 0 1
Read the test file into a dynamic multidimensional array. The program will not have headers, so it will need to read the entire file in order to obtain # of rows/cols.
Once I have all the data in my array I then will be able to manipulate how I want (i.e. swapping columns/rows, reversing order, etc).
At this point I am just trying to get my program to simply output the array as it appears in the test file once the entire matrix has been read in.
Here is what I have written so far:
#include <stdio.h>
#include <stdlib.h>
int main() {
int n;
int i=0;
int j=0;
scanf("%d", &n);
int **array;
array = malloc(n * sizeof(int *));
if(array == NULL) {
printf("Out of memory\n");
exit(1);
}
for(i = 0; i < n; i++) {
array[i] = malloc(n * sizeof(int));
if(array[i] == NULL) {
printf("Out of memory\n");
exit(1);
}
}
for(i = 0; i < n; i++) {
for(j = 0; j < n; j++) {
int k;
scanf("%d", &k);
array[i][j] = k;
printf("%d ", array[i][j]);
}
}
}
And running this gives me output:
9 8 7 6 5 4 3 2 1 0 1 1 1 1 1 1 1 1 1 1 1 1... repeating 1's...
I am not sure what is wrong with my code I have been staring at it for a solid hour and have made 0 progress.
Because my output prints out about 100 different ints I feel that my problem lies in my printing loops, and I feel like it has something to do with int n, but I am not sure how to deal with this.
Any help with be greatly appreciated! Thanks.
The issue is as follows: The first number that is obtained from your file is 10 and that is being stored inside the int n close towards the beginning. That value defines the width and height of your multi-dimensional array, your matrix. You then ask for further values from that file, exactly 10 * 10 many times.
The file, however, only has 4 * 3 - 1 = 11 numbers left in it. It provides them all, right into the int k. Those values get stored inside your matrix, printed. After the 11th (or 12th if you count the first 10) the scanf starts failing. As it fails, it returns the value EOF == -1 but you do not recognize that.
Failure leaves the k as it is, although I am not sure whether it is guaranteed to remain what it previously was, since as far as I know, k could very well have another memory location allocated for itself with each cycle, since (again) as far as I know it gets cleared at the end of each loop. In your case, it does keep its value, luckily I would say, and that gets stored/printed.
In the end, you should have exactly 100 numbers printed, because of that 10 at the very beginning.
Even if you had an additional 4 at the very beginning, you'd end up with a matrix that has a wild last line with all 1s.
If you want to have a 3 by 4 matrix in your hands, consider making your file as the following example:
3 4
10 9 8 7
6 5 4 3
2 1 0 1
Then read the first value into an int n and then second one into an int m. Make first memory allocation with malloc( n * sizeof * array );, then the secondary allocations with malloc( m * sizeof ** array );.
You could also alternatively omit reading anything, deduce how many rows and columns your matrix should have by reading the amount of new-line '\n' occurrences in your file (plus one), as well as amount of numbers there are on a single line.
Edit:
Okay, let's show this you could also part: This is just an example, I'll be using a pair of scanfs for counting both the amount of lines that have at least one number inside and amount of numbers on a single line.
...
int n = 0;
int m = 0;
int discardable;
while ( scanf( "%d", &discardable ) == 1 ) {
// as long as a number has been successfully read
n++;
if ( scanf( "%*[^\n]" ) != 0 )
// discard everything until a '\n'
// and if you fail to encounter a '\n' anywhere until the file ends...
break;
}
// rewind back to the beginning of the file
rewind ( stdin );
while ( scanf( "%d", &discardable ) == 1 ) {
// as long as a number has been successfully read
m++;
if ( scanf( "%*[ \t]" ) != 0 || stdin->_ptr[0] == '\n' )
// discard every ' ' or '\t'
// if you rather get carried until the end of file, break
// else, if the upcoming character is '\n', again, break
break;
}
rewind ( stdin );
...
There you have it, n and m here should be storing the height and width of the matrix you should have, respectively.
This is just a way to do it, I can see why many could potentially just hate this, because I have made use of the FILE structure, and referred to _ptr, but whatever. I personally would prefer this any day over carrying a temporary character array and read from it.
The code below requests 5 numbers and prints asterisks of given numbers. How does number variable remember 5 numbers? Doesn't the next number entered destruct value inside variable? I don't understand. Can you explain it to me?
Below code gives output:
Enter 5 numbers between 1 and 30: 28 5 13 24 7
****************************
*****
*************
************************
*******
#include <stdio.h>
int main( void ){
int i;
int j; /* inner counter */
int number; /* current number */
printf( "Enter 5 numbers between 1 and 30: " ); /* loop 5 times */
for ( i = 1; i <= 5; i++ ) {
scanf( "%d", &number ); /* print asterisks corresponding to current input */
for ( j = 1; j <= number; j++ )
printf( "*" );
printf( "\n" );
} /* end for */
return 0;
}
The answer to your question is:
The text will be dumped in the stdin when you press "enter". scanf(..) reads from the stdin and thus parses all the 5 integers for you (one by one). scanf will only block if stdin is empty. So the values are not store in the number variable but on stdin.
It's because the printing happens in between each read. Notice that scanf is inside the loop for ( i = 1; i <= 5; i++ ) and so is the second loop for ( j = 1; i <= number; j++ ).
So what actually happens is:
1. Read input into number
2. Print asterisks
3. Goto 1.
The code does not actually remember all 5 numbers - it only remembers the current number.
Yeah it is very IQ type Question. Look at the Line
printf( "Enter 5 numbers between 1 and 30: " );
than their is a "for loop" to take values. This loop cover the rest of the code.
So when first "number" take value the 2nd "for loop" starts it works & after finishing return to the 1st "for loop" to take the 2nd Input from keyboard & so on...
It doesn't hold all 5 numbers. Your code sets the value of number and then prints the relevant number of * characters. It then receives a new value on successive iterations of your first for loop. The variable is re-used, rather than being set to multiple values at the same time.
Everytime you enter a number in the program, 'int number' gets set to that number.
The old value has been replaced and is no longer accessible.
Read about it here http://en.wikipedia.org/wiki/Variable_(computer_science)
May I suggest not starting programming with C and maybe starting with something like Python.
Can someone please break down this code for me? I know it changes text from a user file and I know it could be very useful to me. What is the purpose of "~"? How could I amend this code to read a user file word by word and then change it using the same kind of formula?
// first value in the file is the key
if ( fread(&key, sizeof(char), 1, infile) )
{
key = ~key;
}
while( fread(&fval ,sizeof(short), 1, infile) )
{
fputc( (fval / 2) - key, outfile );
}
key = ~key swaps all the bits of key
You know about bits?
ascii A (65) is 100 0001 in binary, so '~' of this is simply swaps each 1 for 0 and each 0 for 1 giving 011 1110 (62) which is >
So this will replace all the As in your document with > and similarly for every other character. The nice thing about ~ is that it's exactly the same process to decrypt - just swap each bit back.
ps. It's not exactly mil-spec encryption!
Comments inline!
#include <stdio.h>
int main(void)
{
/* Integer value of 'A' is 65 and
binary value is 01000001 */
char a='A';
printf("a=%d\n", a);
/* ~a is binary inverse of a so
~01000001 = 10111110 */
a=~a;
printf("a=%d\n", a);
/* easier example */
/* ~0 = 11111111 times # of bytes needed
to store int (whose value is nothing
but negative one) */
int i=0;
printf("i=%d\n", i);
i=~i;
printf("i=%d\n", i);
return 0;
}
$ ./a.out
a=65
a=-66
i=0
i=-1
$
With the above mentioned hint, could you please try and read the code and share your comments.
OTOH, what is crypt? what is its type? what is the value stored in it?!
For more bitwise operations, please refer this page!
I am trying to convert from any base to base 10. For an input of 010111 base 2 it gives me 1, and for 35 base 9 it gives me 18 which should be 38. Any suggestions?
#include<stdio.h>
#include<math.h>
#include<string.h>
#define LENGTH 6
double pow( double x, double power );
int main()
{
char input[LENGTH+1] ;
int base;
unsigned decValue ;
char values[] = "0123456789ABCDEFG";
int i;
puts( "Enter a value, and its base: " );
scanf( "%s", &input );
scanf( "%i", &base );
for( i = LENGTH-1 ; i >= 0; i-- )
{
int index = strchr(values, input[ i ] ) - values;
decValue += index * pow( base , i - LENGTH + 1 );
}
printf( "%s (base-%u) equals %u \n", input, base, decValue );
return 0;
}
The thing that troubles me here the most is your mixture of floating point arithmetic into an integer problem. Not only is it less efficient, but when the result is converted back to an int, there's the possibility it might get rounded down or something silly. Hypothetical example:
double n = pow(2,3); //becomes 7.99999999999999999999999 for some silly reason
int in = n; //rounds down to 7
Although this might not even be happening in your case, be wary of integer <-> floating point conversions, and avoid them when they are unnecessary.
A better solution is to build up the power incrementally. If I were you, I'd iterate from beginning to end of the number. Pseudocode:
let s be the input string's digits;
let r be the radix;
let n be the resulting number;
n=0;
for (i=0; i<s.size(); i++) {
n *= radix;
n += s[i];
}
The concept is that you are picking up digits and shifting them into the number. E.g. 123 in decimal:
1
(shift 1 left, then add 2)
12
(shift 12 left, then add 3)
123
Shifting left, in the context of integers in a given base, is simply multiplying by the radix.
Since i < LENGTH, i - LENGTH + 1 is negative and the pow is therefore 0.
So, you should use pow( base , LENGTH - i - 1 ) -- that one's the biggie. Other big bugs: you should use strlen(input) wherever you're using LENGTH; and you should initialize decValue to 0. There may be others, I stopped looking after the first three (this IS after all California, land of the "Three Strikes, You're Out" law;-).
My suggestion: Dont reinvent the wheel.
See strtoul function:
#include <stdlib.h>
#include <stdio.h>
int main(){
/* first arg: number in base n to convert to base 10
* third arg: base n
*/
long int b10= strtoul("111",NULL,2);
printf("%ld\n",b10);
return 0;
}
You're adding to decValue before you ever assign anything to it. I didn't look too closely at your logic but that stood out immediately. Depending on platform that may cause you issues.
A few comments:
As written, your code doesn't support "any base", only bases up to 17 (an odd place to stop).
strchr() can return NULL. You should never assume that it won't, especially when you're feeding it direct user input.
Lowercase letters are nice, and you should support them. Simply convert the relevant character to uppercase with toupper(), and then you can recognize both a and A as hexidecimal 10.
In the interest of coding practices, I would suggest creating a function to perform the relevant conversion, rather than doing all the dirty work in main().
If you're doing this as a learning exercise, ignore this paragraph, but you appear to essentially be rewriting the standard library function strtol(), which converts a string to a long for arbitrary bases. It's pretty nice, actually, and has some functionality that you could incorporate into your code if you wanted.
Couple things: don't take the address of input (input, an array, already degrades to the pointer you want; taking a pointer of it will result in a pointer to an array, not what you want); and you need to make sure not to overflow the input buffer when reading into it.
If this is not homework, you should just use strtol():
#include <stdlib.h>
#include <stdio.h>
#define Str(x) #x
#define Xstr(x) Str(x)
int main()
{
char input[LENGTH+1] ;
int base;
long decValue;
char *endptr;
puts( "Enter a value, and its base: " );
scanf( "%" Xstr(LENGTH) "s", input ); /* reads at most LENGTH characters */
scanf( "%i", &base );
decValue = strtol( input, &endptr, base );
assert( *endptr == '\0' ); /* if there are any characters left, then string contained invalid characters */
printf( "%s (base-%u) equals %ld\n", input, base, decValue );
return 0;
}