I want this code to randomize character elements instead of integers. But these character elements are from a list of sentences, like so:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void yodificacio(char arr[], int index[], int n);
int main()
{
const char *arr[] = { "Hello how are you", "I'm good.", "Okay! See you later" };
int index[] = { 1, 2, 0 };
int n = sizeof(arr) / sizeof(arr[0]);
printf("%d", n);
printf("%s", arr[1]);
yodificacio(arr, index, n);
printf("Reordered array is: \n");
for (int i = 0; i < n; i )
printf("%s ", arr[i]);
return 0;
}
void yodificacio(char arr[], int index[], int n)
{
int temp[n];
// arr[i] should be present at index[i] index
for (int i = 0; i < n; i )
temp[index[i]] = arr[i];
// Copy temp[] to arr[]
for (int i = 0; i < n; i ) {
arr[i] = temp[i];
index[i] = i;
}
}
(I don't want to change the index by one -> 0,1,2 -> 1,2,0. I want any order, 2,0,1 too etc.)
Note that index variable is for the order I want the character arr[] to be placed in.
If I set the index to {0,1,2}, works perfectly, but when I change the order, ASCII symbols shows up at the print section.
So I want the output to be: I'm good. See you later. Hello how are you.
Here is the original code for integers: (this one works perfectly fine, extracted from internet)
#include <stdio.h>
void reorder(int arr[], int index[], int n);
int main()
{
int arr[] = { 50, 40, 70, 60, 90 };
int index[] = { 4, 3, 2, 1, 0 };
int n = sizeof(arr)/sizeof(arr[0]);
reorder(arr, index, n);
printf("Reordered array is: \n");
for (int i = 0; i < n; i )
printf("%d ", arr[i]);
return 0;
}
void reorder(int arr[], int index[], int n)
{
int temp[n];
// arr[i] should be present at index[i] index
for (int i = 0; i < n; i )
temp[index[i]] = arr[i];
// Copy temp[] to arr[]
for (int i = 0; i < n; i ) {
arr[i] = temp[i];
index[i] = i;
}
}
CodePudding user response:
An important insight here is how similar are the original code and it's modification to reorder character strings. The view below comes from diff --side-by-side, and you can see that the only difference is the type declaration of the parameter arr and, consequently, the copy temp.
The key is that in C, a pointer is just another data value. A character string is a NUL-terminated array of characters; in the various library functions which work with character strings, the string is represented by a pointer to its first character (that is, the decayed value of the character array), but for purposes like this (and others), there is nothing special about the pointer.
void reorder(int arr[], int index[], int n) | void reorder(char* arr[], int index[], int n)
{ {
int temp[n]; | char* temp[n];
for (int i = 0; i < n; i ) for (int i = 0; i < n; i )
temp[index[i]] = arr[i]; temp[index[i]] = arr[i];
// Copy temp[] to arr[] // Copy temp[] to arr[]
for (int i = 0; i < n; i ) { for (int i = 0; i < n; i ) {
arr[i] = temp[i]; arr[i] = temp[i];
index[i] = i; index[i] = i;
} }
} }
The one complication is the use of const, which I removed from the code above. (So you'll need to change const char *arr[] to char *arr[] in your main() function as well.)
const is certainly more accurate. The various strings pointed to by elements in arr are all immutable (at least, in this case), and reorder does not attempt to modify any of them. (It just reorders the pointers; it never looks at what the pointers point at.)
However, C imposes strict requirements on the agreement between the constness of function arguments and function parameters; you cannot call a function which expects const char*[] with an argument of type char*[], nor vice versa. (It's fine to call a function which expect char* with an argument of type const char*. The problem comes with the second level of indirection.)
So if you needed to handle both arrays of immutable character strings and arrays of mutable character strings, you'd need two versions of reorder with two different parameter types, one const and the other not. That's too much code duplication, so I chose to remove the const in this case.
CodePudding user response:
"I want this code to randomize character elements instead of integers. But these character elements are from a list of sentences"
From this, it would not be hard to think your intent was to scramble all the characters within each string, but from the context in your code I concluded that the intent is to reorder the 3 strings, not the characters within the strings. (I asked in comments if this was so, but not answered at time this answer was posted. Please comment if this is an incorrect conlusion)
As noted in comments, your code is close to working, with the exception of producing randomization. This answer will identify steps to address all of these, and one or two more minor things.
First, with warnings turned on the following items should be flagged:
int main()is not a prototype. the minimum prototype for main isint main(void)- incompatible pointer types passing
const char *[3]to parameter of typechar * - and related: implicit conversion loses integer precision:
inttochar
This is because the prototype
void yodificacio(char arr[], int index[], int n);
but arr is defined as:
const char *arr[] = {"...","...","..."}
There are several ways to change one or both to make them compatible, for your purpose it would be fine to leave the definition of arr as is, and change the prototype to be:
void yodificacio(int n, char *arr[n], int index[n]);//note the change in order of parameter types.
- Next incompatible pointer to integer conversion assigning to
intfromchar *
This warning occurs in yodificacio() because
int temp[n];
does not support the following assignment:
temp[index[i]] = arr[i];// type of temp is not the same as arr
Suggest changing temp
char *temp[m];//changed to match type of arr
This takes care of all warnings. The only thing left is randomization of the order that the strings are contained in arr.
This requires an algorithm for generating a random permutation of a finite sequence, in your case requiring 3! (==6) permutations to populate the index[3] array. Algorithms that can do this are described in sufficient detail here. Additionally, in support of randomizing index, it might be worth considering making it similar to arr so the six addresses point to the 6 permutations needed:
int *index[] = {{ 0,1,2},{1,2,0},{2,0,1},{ 1,0,2},{ 0,2,1},{ 2,1,0}};
And it follows, update the prototype to accommodate the new index
void yodificacio(int n, char *arr[n], int *index[n]);
