How do I unscramble a scrambled word? - arrays

Supposed I have an array of char {A,B,C,D,E,F} and the order number is 3
Then, the scrambled word is as follow :
The first 3rd (order number) character, C is removed and saved.
{A,B,D,E,F} , {C}
Start from the following character which is D, and the first third character would be F. So, F is removed and saved.
{A,B,D,E} , {C,F}
Start from the following character (since it reached end of array index, we go back to the beginning). So start from character A, and the first third character is D.
{A,B,E} , {C,F,D}
and so on.
The resulting will be an empty original char array, and the scrambled array
{ } , {C,F,D,B,E,A}
The above algorithm can be easily implemented. I have no problems with that. What I do have problem with is unscrambling it. I am given some unscrambled char array, and its ordering, and I have to find its original char array.
I have been trying for hours now and I can't seem to find a "formula" for it. I'm guessing I'm missing something crucial. Can anyone give me a clue or hint on how to approach this problem?

Make "map string" the same length as your original, but with all the letters in sequence, like "ABCDEFGH.."
Scramble it according to the given ordering
Now, iterate through your problem string and the map string at the same time. For each character in the problem string, the map string character will say where to put it. If you have map="SQEG..." and problem="DSEG...", then 'D' goes in the 'S' position, 'S' goes in the 'Q' position, etc.
That's it. If you prefer, or if your problem string is too long, use an array of integers instead of a string for the map.

Related

Having hard time understanding how to us void printSp(int) in this given task,

I only really understand how to do equation in program I need help on how to approach this task, also I not really sure whats its asking of me to do.
Suppose you are given a function with the following declaration:
void printSp(int); /* prints specified number of spaces */
Write a function named printTri that takes a single argument, a character, and returns an integer value. If the character is not a capital letter (between 'A' and 'Z'), then the function simply returns 0. Otherwise, if it is a capital letter, the function will print a triangle of characters that looks like this: A ABA ABCBA ABCDCBA
NOTE: WIth a fixed-width font, the center letter in each row would line up. Write this out for yourself on paper, to figure out how many spaces should be printed on each line before the characters start. The bottom line has zero spaces. How many spaces should the top line have? The letter passed in becomes the highest letter in the triangle. For example, to print the triangle above, the caller passes in 'D'. After printing, the function returns the total number of non-space characters printed. For example, for the example triangle above, the function must return 16. You must call the printSp function, once per line, as part of your solution. (NOTE: Call printSp for every line, even when the number of spaces to print is zero.) History:
This is what I have so far I know its not much but its all I understand how to do.
if (x >='A' && x <= 'Z') printf(" A\n ABA\n ABCBA\nABCDCBA")
else return 0;
The function printSp() prints spaces.
You currently are outputting a hard coded number of spaces instead of using printSp(). Swap printf(" ") for printSp(3)
Reading the question, they want you to output a variable number of rows based on the letter provided. So for D you print the pattern you have hard coded which contains four rows and enough letters to output the D. For E you add another row.
I generally suggest students approach problems like this by starting with hardcoding, as you have. Ensure that you incorporate the required features, like printSP(). Then make the code more generic to handle other inputs.

How to check if two words are anagrams in c

I am trying to create a programme that is able to determine whether two inputted words are anagrams of each other.
The way in which I have been told to go by my tutor is to count how many of the first letter of one word there is, then compare to the other, then repeat for the rest of the letters. Therefore if the word gets to the end, then it considers them anagrams. However that is all he has helped me with, and I am really struggling with the problem.
The programme is required to print whether or not they are anagrams like so,
Success! "Carthorse" and "Orchestra" are anagrams!
Edit: Thanks guys for all of your responses, whilst I understand the whole idea behind them, I am finding it very difficult to put them into code, would anyone be able to simply writing the annotated code for me? It's not for a homework or anything, it's simply a personal project.
It sounds like you're new to C! Welcome :)
Tasks like that can seem complex, so the first step I'd do here is break it down into steps that you can google for how to do. So:
"count how many of the first letter of one word there is, then compare to the other, then repeat for the rest of the letter"
Read in the words/create variables of them
Create an array of length 26, to store each letter of the alphabet
Loop through the first word and for each letter, add one to the correct array index (a = 0, m = 12, etc)
e.g.
int index = string[i] - 'a'; // This will subtract the ascii value from the letter, getting a = 0 etc
letterCounts[index]++; // or letterCounts[index]--;
Loop through the second word, and for each letter, subtract one from the array index
If at the end any index is not 0, it is not an anagram.
Convert both strings to lowercase characters.
Create two arrays of 26 characters for the letters of the alphabet.
Run through each string counting the letters and incrementing the appropriate element in the alphabet arrays.
Then compare the two alphabet arrays and if they are equal for each character, your strings are anagrams.
1) Convert both strings to lowercase as necessary (use tolower from ctype.h).
2) Sort each string, e.g., by using qsort from stdlib.h:
static int cmp(const void *a, const void *b) { return *(char *)a - *(char *)b; }
qsort(str1, strlen(str1), 1, (cmp));
qsort(str2, strlen(str2), 1, (cmp));
3) Compare the sorted strings with strcmp from string.h - if equal, they are anagrams, otherwise not.

C language, char=char with unexpected results

Hi everybody and thanks in advance for any help, this is the situation:
#define N 12
[..]
char vect[N][2];
char strng[2];
[..]
vect[i][0]=strng[2]; //this two lines are in a simple for cycle
vect[i][2]=strng[0];
Now, if in string[2] I have "c 2", what I expect in vect[i][0] is '2' and in vect[i][1] 'c'.
I use code::blocks and watching vect I have instead "2#", but it could be "2À" as well.
Can you help me? Where am I wrong?
Array indexes goes from zero up to the size minus one. So using e.g. strng[2] you access the third entry in the two-entry array. Accessing an array out of bounds leads to undefined behavior and the data will be indeterminate.
You should also remember that all strings in C are one more character than reported by e.g. strlen, and that extra character is a special terminator character. So if you want a two-character string, you really need three characters: Two for the string, and one for the terminator.
Rewrite these statements
vect[i][0]=strng[2]; //this two lines are in a simple for cycle
vect[i][2]=strng[0];
the following way
vect[i][0]=strng[1]; //this two lines are in a simple for cycle
vect[i][1]=strng[0];
provided that string contains two characters { 'c', '2' }.
Take into account that array string can not have string literal "c 2", because you defined it as
char strng[2];
that is it can contain only two characters.
If you want that the array would contain indeed "c 2" then you have to define it either as
char strng[3];
or as
char strng[4];
if you want to include the terminating zero.
In this case you may write
vect[i][0]=strng[2]; //this two lines are in a simple for cycle
vect[i][1]=strng[0];
Assuming strng literally contains "c 2", then your memory is the issue. strng[2] contains 3 cells iirc. 2 for holding chars and then a null terminator (ie \0). so when you try to access strng[2], (which you cant because you can only go to N-1 cells, where N is the number allocated for it) it contains undefined results, since it isnt null terminated and you are reaching beyond memory you allocated

Arrays as function parameters

I'm trying to write a little CLI Hangman game, just to create something in C using my very limited set of language features, making the information so far stick.
I haven't got to strings in the book yet, so I've created a so-called dictionary, which is a multi-dimensional array of characters, each row representing a word, and each column a letter. Therefore, if I want to put today's Dictionary.com word of the day ("prognosticate") in the dictionary, I write something like
dictionary[MAX_WORDS][MAX_CHARS] = {
...
{'p', 'r', 'o', 'g', 'n', 'o', 's', 't', 'i', 'c', 'a', 't', 'e'},
...
}
Next, I represent the word to be printed on screen as an array of characters, initially made of underscores.
The way I thought of it, when the player enter a letter, I check to see if it exists within the current word. If it does, I replace the underscores in the word[] array with the actual letter. I consider the word to be guessed when there are no underscores left in the word[] array.
The first thought was to write a function int in_array(char array[], char letter) which would return 0 or 1 based on whether the letter is found in the array. But then I figured out I couldn't pass it dictionary[][] as the first argument. I haven't figured out a solution so far, so I'll have to either use two functions, one for each array, or... rethink the whole idea.
So to sum this up, I need a function to check whether an element exists within either a one-dimensional or multi-dimensional array. Any solutions? Thanks in advance!
You can pass the entire dictionary via the somewhat janky
void foo(char dict[][MAX_CHARS], int whichWord);
i.e. by telling the compiler exactly how big each row of the 2D array is in this case, and which row you want as a separate parameter. Then you use your usual 2-subscript notation to access elements.
To pass one row of this array is easy too. Let's say you're doing guesses on the second word:
void foo(char[] word, int numChars);
foo(&(dict[1][0]), MAX_CHARS);
which might be little ahead of where you're at, but says "take the address in memory of the first character in the row I want, the second row (remember: 0-based indexing!), and treat it as the start of a one-dimensional array."
The problem you need to solve with this approach is telling the routine how many characters are in your word. If you use MAX_CHARS you have a problem, because presumably not every word is that length, and the characters you don't assign are uninitialized; i.e. you may have a bunch of garbage chars at the end of your row, one of which might even be the character you're looking for! The customary solution for this is to put a 0-valued character, written '\0', at the end of each word, so the function knows to stop when it sees it. You'd need to add this to the end of each word you're initializing, and you might need to bump MAX_CHARS up too to make room for it, because it is a character like everything else in your word.
A far better solution is to turn your dict into a one-dimensional array of strings, i.e.
char* dict[MAX_WORDS];
but that requires you be comfortable with pointers and strings, so come back to it when you're ready.

Pointers in c (how to point to the first char in a string with a pointer pointing somewhere else in the same string)

If I have a pointer that is pointing somewhere in a string, let's say it is pointing at the third letter (we do not know the letter position, basically we don't know it is the third letter), and we want it to point back to the first letter so we can make the string to be NULL how do we do that?
For example:
if we have ascii as a pointer
ascii is pointing now somewhere in the string, and i want it to point at the first char of the string how do i do that?
(Note:
I tried saying
int len = strlen(ascii);
ascii -= len;
ascii = '0';
but it is not working, it changes wherever the pointer is to 0 but not the first char to 0)
You cannot. C and C++ go by the "no hidden costs" rule, which means, among other things, noone else is going to secretly store pointers to beginnings of your strings for you. Another common thing is array sizes; you have to store them yourself as well.
First of all, in your code, if ascii is a pointer to char, that should be
*ascii = '\0';
not what you wrote. Your code sets the pointer itself to the character '0'. Which means it's pointing to a bad place!
Second of all, strlen returns the length of the string you are pointing to. Imagine the string is 10 characters long, and you are pointing at the third character. strlen will return 8 (since the first two characters have been removed from the calculation). Subtracting this from where you are pointing will point you to 6 characters before the start of the string. Draw a picture to help see this.
IMHO, without having some other information, it is not possible to achieve what you are wanting to do.
From what I said above, you should be able to work out what you need to do as long as you keep the original length of the string for example.
No. You, however, can make it point at the last character of the string, which is right before '\0' in every string (it's called zero-terminated string).
What you could do is instead of a char* you could use a pointer to a struct which contains the information you need and the string.
It's not guaranteed to work, but you might get away with backing up until you find a null character, and then moving forward one.
while(*ascii) ascii--;
ascii++;

Resources