Output mistake in array - c
int BruteForceStringMatch(char Text[], char Pattern[]){
int TextSize = sizeof(Text) / sizeof(Text[0]); //get size of arrays
int PatternSize = sizeof(Pattern) / sizeof(Pattern[0]);
int i;
for(i = 0; i++; i < TextSize - PatternSize){
int j = 0;
while(j < PatternSize && Pattern[j] == Text[i + j]){
j = j + 1;
}
if(j = PatternSize){
return i;
}
}
return -1;
}
int main() {
char x [] = "if" ;
char y [] = "aslifee";
int c = BruteForceStringMatch(y,x);
printf("%d ",c);
getchar();
}
Hi everyone, I want to match text and pattern by using BruteForceStringMatch function but I get output -1 from computer. Here I should get 3 (because fourth element is matching) but why am I getting -1 which means there is no matching?
Here is what is wrong:
int TextSize = sizeof(Text)/sizeof(Text[0]); //get size of arrays
This does not give you the size of the array, because C passes arrays to functions as if they were pointers. The size of the array is stripped from it, so sizeof returns the size of the pointer.
Use strlen instead:
int TextSize = strlen(Text);
Same goes for the pattern size.
Note: I assume that you are doing this as a learning exercise, because C standard library supplies a function for finding strings within strings.
Related
attach second text array on given position
How can i attach one text array to another text array in c on a given position. For example from input user enters 2 arrays and one digit which is the position. ( _ is empty space ) first: hi my name is ,i learn c second: Jacob_ pos: 14 result hi my name is jacob ,i learn c here is my code #include<stdio.h> #include<string.h> #include<ctype.h> void attach(char *a,char *b,char*c,int pos){ int i,j; for(i = 0; i < pos;i++){ *(c+i) = *(a+i); } int lenB = strlen(b); for(i = pos+1;i < lenB;i++){ *(c+i) = *(b+i); } int lenRes = lenB+pos; int lenA = strlen(a); for(i = lenRes;i < lenA;i++){ *(c+i) = *(a+i); } puts(c); } int main() { char a[1000],b[1000],c[1000]; gets(a); gets(b); int pos; scanf("%d",&pos); attach(a,b,c,pos); return 0; }
Most of your logic for accessing the strings or doing the loops was just wrong. For example, your second for loop would have zero iterations whenever the user specifies a pos such that pos + 1 >= lenB, so that can't be right. You also forgot to add a null termination character at the end of the string. I kept the basic structure of your program, but cleaned up some minor things and fixed the logic. #include <stdio.h> #include <string.h> void attach(const char * a, const char * b, char * c, int pos) { int i; for (i = 0; i < pos; i++) { c[i] = a[i]; } int lenB = strlen(b); for (i = 0; i < lenB; i++) { // I fixed this line c[pos + i] = b[i]; // I fixed this line } int lenA = strlen(a); for (i = pos; i < lenA; i++) { // I fixed this line c[i + lenB] = a[i]; // I fixed this line } c[lenA + lenB] = 0; // I added this } int main() { char c[1000]; attach("Hi my name is , I learn C", "David", c, 14); puts(c); // I moved this to a better place } This program produces the output "Hi, my name is David, I learn C". By the way, c[i] is equivalent to *(c + i), so use whichever syntax you find more readable. Also, to help you find better answers with Internet searches in the future, this operation is not usually called "attach". It is usually called "insert". And we don't call these things "text arrays", we call them "strings". So a better way to ask your question is: "How can I insert a string into the middle of another string?"
Length of array of strings
How can we determine the length of an array of strings when we don't know the length? For example in this piece of code: #include <stdio.h> int main() { int n; char names[3][10] = { “Alex”, “Phillip”, “Collins” }; for (n = 0; n < 3; n++) printf(“%s \n”, names[n]); } n < 3 is assuming you know the length of the array but how can you determine it's length when we don't know? I have tried a few alternatives such as: int arraySize() { size_t size, i = 0; int count = 0; char names[3][10] = { “Alex”, “Phillip”, “Collins” }; size = sizeof(names) / sizeof(char*); for (i = 0; i < size; i++) { printf("%d - %s\n", count + 1, *(names + i)); count++; } printf("\n"); printf("The number of strings found are %d\n", count); return 0; } or for (n = 0; n < sizeof(names); n++) but they all error out. Any help is appreciated.
I am not sure what you mean by they all err out. There is a syntax issue in the code posted as you use guillemet characters instead of double quotes: “Alex” should be "Alex". This could be a side effect of your cut/paste method to post the code, but nevertheless a potential issue. Your approach using size = sizeof(names) / sizeof(char*); is right but the type is incorrect: names[0] is not a char *, it is an array of 10 characters. You should use size = sizeof(names) / sizeof(names[0]); which works for all arrays, regardless of the type. Here is a modified version where the length of the array is determined by the compiler: #include <stdio.h> int main() { char names[][10] = { "Alex", "Phillip", "Collins" }; int i, length = sizeof(names) / sizeof(names[0]); for (i = 0; i < length; i++) printf("%d: %s\n", i + 1, names[i]); return 0; } Notes: you could use size_t instead of int for array length and index variables, but it is only necessary for very large arrays and the printf conversion specifier would be %zu for a value of type size_t. it is less confusing to use length for the length of an array and reserve size for sizes in bytes obtained from sizeof().
first every string is ended with a special character '\0' means {'A','L','E','X','\0'} even you haven't put '\0' there but compiler put it there for it convenient int lenght(char *str){ int count = 0 ; for(int i=0;str[i]!='\0';i++){ count++ ; } return count ; } use this function to count your string length like : int main(){ char names[3][10] = {"Alex", "Phillip", "Collins"}; printf(“%d \n”,lenght(names[1] ); return 0 ; }
Find the difference between elements in an array and store the results in a new array
This is my current code: #include <stdio.h> int index_x[] = {0,0,1,0,1,0,0,0,1,0,0,1,0}; // any number of elements int len = sizeof index_x / sizeof*index_x; int main(void) { int arr[len]; int j = 0; for (int i = 0; i < len; i++) if (index_x[i]) arr[j++] = i; // save and advance j only if value is "1" for (int i = 0; i < j; i++) // only print below j ! printf("%d\n", arr[i]); } Output: 2 4 8 11 From this output, I would like to generate another array that is the difference between these elements. In this case the new array would be {2,4,3}. (2-4=2, 8-4=4, 11-8=3). I am currently struggling with two things: Saving the array generated from the current code arr[i] as a another array so I can manipulate it for future uses. Generating the "differences array". The tricky part is that the number of elements will not be constant so I cannot specify an array size.
It may be helpful to break things out into functions. int indexes_of_non_zero(int *source, size_t len, int **dest) { *dest = malloc(sizeof(int) * len); int count = 0; for (int i = 0; i < len; i++) { if (source[i] != 0) { (*dest)[count++] = i; } } *dest = realloc(*dest, sizeof(int) * count); return count; } So we have a function indexes_of_non_zero that takes a source array of ints with size specified by argument len, and then a pointer to an array of ints that will be the destination for our output. We can naively allocate the same amount of memory to the destination, then loop over the source array and store the indexes of non-zero elements. When we're done, we use count to know the size of destination array. We use realloc to shrink the array to just the needed size. And the key is we return the count so our main function knows how big the destination array is. We can now create a diffs function to do basically the same thing for the differences. int diffs(int *source, size_t len, int **dest) { *dest = malloc(sizeof(int) * (len - 1)); for (int i = 0; i < (len - 1); i++) { (*dest)[i] = abs(source[i] - source[i + 1]); } return len - 1; } Putting it all together (not copying and pasting the function implementations for terseness) with a main function, and remembering to free the memory we've used, we get: #include <stdio.h> #include <stdlib.h> #include <math.h> int indexes_of_non_zero(int *source, size_t len, int **dest); int diffs(int *source, size_t len, int **dest); int main(void) { int data[] = {0,0,1,0,1,0,0,0,1,0,0,1,0}; size_t len = sizeof(data) / sizeof(*data); int *nz = NULL; int *d = NULL; int nzc = indexes_of_non_zero(data, len, &nz); int dlen = diffs(nz, nzc, &d); for (int i = 0; i < nzc; i++) { printf("%d\n", nz[i]); } for (int i = 0; i < dlen; i++) { printf("%d\n", d[i]); } free(nz); free(d); } And compiling and running it, the output is: 2 4 8 11 2 4 3
I changed it to get the differences as direct as possible; the inner loop is very simple. The size question, first part: I (still) tried to avoid size_t for the input but added some sanity check for the size. Just to show there is a limit. part two: a first loop to get the sum of true values in advance. Also the booldata array consists of chars and is not called index_x. Index is i. part three: the diffs VLA gets its exact size, which can be 0 even for huge inputs. Some test could be added here after counting, to rule out a (big) input full of "1". I added the copying, with message and printout. #include <stdio.h> #include <string.h> char booldata[] = { 0,0,1,0,1,0,0,0,1,0,0,1,0 }; char sz_overf = sizeof booldata > 0xffffL * 0xffff; // too-big-flag for exiting... int len = sizeof booldata / sizeof * booldata; // ...to keep len below size_t int sum_of_trues (char *booldata, int len) { int sum = 0; for (int i = 0; i < len; i++) if (booldata[i]) sum++; return sum; } void print_intarr(int *inta, int len) { for (int i = 0; i < len; i++) printf("%d\n", inta[i]); } int main(void) { if (sz_overf) return 100; // len might be overflowed int unsigned // signed provokes VLA warning: 9 gazillions seems ok, but not 18 dsum = sum_of_trues(booldata, len) - 1; // Invest a counting loop int diffs[dsum], // VLA di = 0; // diffs' index int sti = -1; // Stored last index containing true for (int i = 0; i < len; i++) if (booldata[i]) { // true? if (sti >= 0) { // and is there a left neighbour? int diff = i - sti; // how far away? printf("%d\n", diff); // 1. on-the-fly result diffs[di++] = diff; // 2. for keeps } sti = i; // remember last "true" } printf("Copying %zu bytes from Diff.-Array\n", sizeof diffs); int diffscopy[sizeof diffs]; memcpy(diffscopy, diffs, sizeof diffs); print_intarr(diffscopy, dsum); // dsum or sizeof diffs return 0; } output: 2 4 3 Copying 12 bytes from Diff.-Array 2 4 3 The inner loop could look like this w/o multi-option: if (booldata[i]) { if (sti >= 0) // and is there a left neighbour? diffs[di++] = i - st; // 2. for keeps sti = i; } Two arrays and three variables. The rest is needed to make this work. BUGS: all-false input segfaults. It takes one "true" to get zero diffs...
Is there a algorithm to print all arrengments of subsequences of an array?
I am working with combinatorics and I would like to know if there is an algorithm that prints all arrangments of subsequences of a given array. That is, if I give to this algorithm the sequence "ABCDEF" it will print : A, B, C, D, E, F, AB, AC, AD, AE, AF, BC, BD, BE, BF, CD, CE, CF, DE, DF, EF, ABC, ABD, ABE, ABF, ACD, ACE, ACF, ADE, ADF, AEF, BCD, BCE, BCF, BDE, BDF, BEF, CDE, CDF, CEF, DEF, ABCD, ABCE, ABCF, ABDE, ABDF, ABEF, ACDE, ACDF, ACEF, ADEF, BCDE, BCDF, BCEF, BDEF, CDEF, ABCDE, ABCDF, ABCEF, ABDEF, ACDEF, BCDEF, ABCDEF, or for a more simple case, if i give it 1234, it will print: 1,2,3,4,12,13,14,23,24,34,123,124,134,234,1234. As you can see it is not an arbitrary permutation it is only the permutation of the last members of a subsequence in a way it still reains a subsequence. I have tried to make a function in c that does this but i got really confused, my idea would be to make a int L that keeps the size of the subsequence,and another tree integers one that keeps the head of the subsequence, one that marks the separation from the head and one that slides trought the given number of characters, but it gets too confused too quickly. Can anyone help me with this ? my code is: int Stringsize( char m[] ){ int k; for(k=0;;k++){ if( m[k] == '\0') break; } return (k-1); } void StringOrdM(char m[]){ int q,r,s,k; for(k=0;k<=Stringsize(m);k++) for(q=0;q<=Stringsize(m);q++) for(s=q;s<=Stringsize(m);s++ ) printf("%c",m[q]); for(r=q+1; r<=Stringsize(m) && (r-q+1)<= k ;r++ ) printf("%c", m[r] ); } And for ABCD it prints A,A,A,A,B,B,B,C,C,D,AA,AB,AC,AD,BC,BD,CC,CD,DD,... so it is not right because it keeps repeating the A 4 times the B three times and so on, when it should have been A,B,C,D,AB,AC,AD,BC,BD,CD,...
As I said in my comment above, one solution is simple: count in binary up to (1<<n)-1. So if you have four items, count up to 15, with each bit pattern being a selection of the elements. You'll get 0001, 0010, 0011, 0100, 0101, 0110, 0111, 1000, 1001, 1010, 1011, 1100, 1101, 1110, 1111. Each bit is a true/false value as to whether to include that element of the array. #include <stdio.h> int main(void) { //////////////////////////////////////////////////////////////////////// int A[] = { 1, 2, 3, 4, 5 }; //////////////////////////////////////////////////////////////////////// size_t len = sizeof A / sizeof A[0]; // Array length (in elements) size_t elbp = (1<<len) - 1; // Element selection bit pattern size_t i, j; // Iterators // Cycle through all the bit patterns for (i = 1; i<=elbp; i++) { // For each bit pattern, print out the 'checked' elements for (j = 0; j < len; j++) { if (i & (1<<j)) printf("%d ", A[j]); } printf("\n"); } return 0; } If you want the elements sorted shortest to longest, you could always store these results in a string array (using sprintf()) and then sort (using a stable sorting algorithm!) by string length.
I mentioned in a comment above that if you didn't want to use a bit pattern to find all permutations, and sort the results according to whatever criteria you'd like, you could also use a recursive algorithm. I suspect this is a homework assignment, and you only asked for an algorithm, so I left some of the key code as an exercise for you to finish. However, the algorithm itself is complete (the key parts are just described in comments, rather than functional code being inserted). #include <stdio.h> #include <stdlib.h> #include <string.h> void printpermutations(const int *A, const size_t n, const char *pfix, const size_t rd); int main(void) { ///////////////////////////////////////////////////////////////////// int A[] = { 1, 2, 3, 4, 5 }; ///////////////////////////////////////////////////////////////////// size_t n = sizeof A / sizeof A[0]; // Array length (in elements) size_t i; // Iterator for (i = 1; i <= n; i++) { printpermutations(A, n, "", i); } return 0; } // Recursive function to print permutations of a given length rd, // using a prefix set in pfix. // Arguments: // int *A The integer array we're finding permutations in // size_t n The size of the integer array // char *pfix Computed output in higher levels of recursion, // which will be prepended when we plunge to our // intended recursive depth // size_t rd Remaining depth to plunge in recursion void printpermutations(const int *A, const size_t n, const char *pfix, const size_t rd) { size_t i; char newpfix[strlen(pfix)+22]; // 20 digits in 64-bit unsigned int // plus a space, plus '\0' if (n < rd) return; // Don't bother if we don't have enough // elements to do a permutation if (rd == 1) { for (i = 0; i < n; i++) { // YOUR CODE HERE // Use printf() to print out: // A string, consisting of the prefix we were passed // Followed immediately by A[i] and a newline } } else { strcpy(newpfix, pfix); for (i = 1; i <= n; i++) { // YOUR CODE HERE // Use sprintf() to put A[i-1] and a space into the new prefix string // at an offset of strlen(pfix). // Then, call printpermutations() starting with the ith offset into A[], // with a size of n-i, using the new prefix, with a remaining // recursion depth one less than the one we were called with } } }
Depending on torstenvl's answer I did this code and It works perfectly. If there is any problem let me know. #include <stdio.h> #include <stdlib.h> #include <string.h> int main(void) { char str[] = "1234"; size_t len = strlen(str); // Array length (in elements) char *A = malloc(sizeof(char) * len); strcpy(A,str); size_t elbp = (1<<len) - 1; // Element selection bit pattern size_t i, j; // Iterators int a = 0, b = 0, n = 0; char **arr = malloc(sizeof(char*) * (10000)); //allocating memory if (A[0] >= 'A' && A[0] <= 'Z') //If the string given is "ABCD...." transfer 'A' to '1' ; 'C' to '3' ...etc for(int i = 0; i < len; i++) A[i] = A[i] - 'A' + '1'; // Cycle through all the bit patterns for (i = 1; i<=elbp; i++) { arr[b] = malloc(sizeof(char) * len); // For each bit pattern, store in arr[b] the 'checked' elements for (j = 0, a = 0; j < len; j++) if (i & (1<<j)) arr[b][a++] = A[j]; b++; } int *num = calloc(sizeof(int) ,10000); for (i = 0; i < b; i++) num[i] = strtol(arr[i], NULL, 10); //convert char to int for (i = 0; i < b; i++) //sort array numbers from smallest to largest for (a = 0; a < i; a++) if (num[i] < num[a]) { n = num[i]; num[i] = num[a]; num[a] = n; } char *result = calloc(sizeof(char),10000); for (i = 0, a = 0; i<b; i++) a += sprintf(&result[a], "%d,", num[i]); //convert int to char and store it in result[a] result[a - 1] = '\0'; //remove the last ',' len = strlen(result); if (str[0] >= 'A' && str[0] <= 'Z') //if the string given is "ABCD..." transfer '1' to 'A' ; '12' to 'AB' ; '13' to 'AC'.....etc for (i = 0; i < len; i++) if(result[i] != ',') result[i] = 'A' + (result[i] - '1') ; ///test printf("%s",result); return 0; } the output for "1234": 1,2,3,4,12,13,14,23,24,34,123,124,134,234,1234 the output for "123456789": 1,2,3,4,5,6,7,8,9,12,13,14,15,16,17,18,19,23,24,25,26,27,28,29,34,35,36,37,38,39,45,46,47,48,49,56,57,58,59,67,68,69,78,79,89,123,124,125,126,127,128,129,134,135,136,137,138,139,145,146,147,148,149,156,157,158,159,167,168,169,178,179,189,234,235,236,237,238,239,245,246,247,248,249,256,257,258,259,267,268,269,278,279,289,345,346,347,348,349,356,357,358,359,367,368,369,378,379,389,456,457,458,459,467,468,469,478,479,489,567,568,569,578,579,589,678,679,689,789,1234,1235,1236,1237,1238,1239,1245,1246,1247,1248,1249,1256,1257,1258,1259,1267,1268,1269,1278,1279,1289,1345,1346,1347,1348,1349,1356,1357,1358,1359,1367,1368,1369,1378,1379,1389,1456,1457,1458,1459,1467,1468,1469,1478,1479,1489,1567,1568,1569,1578,1579,1589,1678,1679,1689,1789,2345,2346,2347,2348,2349,2356,2357,2358,2359,2367,2368,2369,2378,2379,2389,2456,2457,2458,2459,2467,2468,2469,2478,2479,2489,2567,2568,2569,2578,2579,2589,2678,2679,2689,2789,3456,3457,3458,3459,3467,3468,3469,3478,3479,3489,3567,3568,3569,3578,3579,3589,3678,3679,3689,3789,4567,4568,4569,4578,4579,4589,4678,4679,4689,4789,5678,5679,5689,5789,6789,12345,12346,12347,12348,12349,12356,12357,12358,12359,12367,12368,12369,12378,12379,12389,12456,12457,12458,12459,12467,12468,12469,12478,12479,12489,12567,12568,12569,12578,12579,12589,12678,12679,12689,12789,13456,13457,13458,13459,13467,13468,13469,13478,13479,13489,13567,13568,13569,13578,13579,13589,13678,13679,13689,13789,14567,14568,14569,14578,14579,14589,14678,14679,14689,14789,15678,15679,15689,15789,16789,23456,23457,23458,23459,23467,23468,23469,23478,23479,23489,23567,23568,23569,23578,23579,23589,23678,23679,23689,23789,24567,24568,24569,24578,24579,24589,24678,24679,24689,24789,25678,25679,25689,25789,26789,34567,34568,34569,34578,34579,34589,34678,34679,34689,34789,35678,35679,35689,35789,36789,45678,45679,45689,45789,46789,56789,123456,123457,123458,123459,123467,123468,123469,123478,123479,123489,123567,123568,123569,123578,123579,123589,123678,123679,123689,123789,124567,124568,124569,124578,124579,124589,124678,124679,124689,124789,125678,125679,125689,125789,126789,134567,134568,134569,134578,134579,134589,134678,134679,134689,134789,135678,135679,135689,135789,136789,145678,145679,145689,145789,146789,156789,234567,234568,234569,234578,234579,234589,234678,234679,234689,234789,235678,235679,235689,235789,236789,245678,245679,245689,245789,246789,256789,345678,345679,345689,345789,346789,356789,456789,1234567,1234568,1234569,1234578,1234579,1234589,1234678,1234679,1234689,1234789,1235678,1235679,1235689,1235789,1236789,1245678,1245679,1245689,1245789,1246789,1256789,1345678,1345679,1345689,1345789,1346789,1356789,1456789,2345678,2345679,2345689,2345789,2346789,2356789,2456789,3456789,12345678,12345679,12345689,12345789,12346789,12356789,12456789,13456789,23456789,123456789 the output for "ABCDEF": A,B,C,D,E,F,AB,AC,AD,AE,AF,BC,BD,BE,BF,CD,CE,CF,DE,DF,EF,ABC,ABD,ABE,ABF,ACD,ACE,ACF,ADE,ADF,AEF,BCD,BCE,BCF,BDE,BDF,BEF,CDE,CDF,CEF,DEF,ABCD,ABCE,ABCF,ABDE,ABDF,ABEF,ACDE,ACDF,ACEF,ADEF,BCDE,BCDF,BCEF,BDEF,CDEF,ABCDE,ABCDF,ABCEF,ABDEF,ACDEF,BCDEF,ABCDEF
Combinations, or k-combinations, are the unordered sets of k elements chosen from a set of size n. Source: http://www.martinbroadhurst.com/combinations.html This is the code: unsigned int next_combination(unsigned int *ar, size_t n, unsigned int k) { unsigned int finished = 0; unsigned int changed = 0; unsigned int i; if (k > 0) { for (i = k - 1; !finished && !changed; i--) { if (ar[i] < (n - 1) - (k - 1) + i) { /* Increment this element */ ar[i]++; if (i < k - 1) { /* Turn the elements after it into a linear sequence */ unsigned int j; for (j = i + 1; j < k; j++) { ar[j] = ar[j - 1] + 1; } } changed = 1; } finished = i == 0; } if (!changed) { /* Reset to first combination */ for (i = 0; i < k; i++) { ar[i] = i; } } } return changed; }
All Integers have the same value
So I am working on some homework, in which I have to create a global array of 500 random integers between 0 and 99. Then, I have to count how many are greater than 75, and how many are less than 50. Here is my code: #include <stdlib.h> #include <stdio.h> static int ARRAY[500]; static char str[1]; void main() { int i = 0; for (i = 0; i < 500; i++) { int r = rand() % 99; ARRAY[i] = r; } int gt75 = count75(); int lt50 = count50(); printf("%d\n", str, gt75); printf("%d\n", str, lt50); } int count75() { int i = 0, counter = 0; for (i = 0; i < 500; i++) { int n = ARRAY[i]; if (n > 75) { counter += 1; } } return counter; } int count50() { int i = 0, counter = 0; for (i = 0; i < 500; i ++) { int n = ARRAY[i]; if (n < 50) { counter += 1; } } return counter; } However, after compiling and running my program, I get the following output: 4225008 4225008 This can't be right, as the list should only have 500 elements in the first place. What am I doing wrong?
You have two errors. First, int r = rand() % 99; should be int r = rand() % 100; Otherwise you just get numbers between 0 and 98. Second, your printf statements are odd. They should be: printf("Greater than 75: %d\n", gt75); printf("Less than 50: %d\n", lt50); In the current printf statements, the str is cast to an int, which is interpreting the str pointer as an int, thus your strange output.
You're printing a char array with printf using "%d", which is for printing integers. Use "%s" for printing char arrays: printf("%s\n", str, gt75); Or, if you're trying to print the value of gt75 as an integer: printf("%d\n", gt75); I do not know why you would pass str in this case, though. When you use "%d", you are telling printf to interpret the input as an int. Since str is actually a char array, it does not output correctly. Instead, you're printing the memory location of str, which is the value of an array.
You are always printing the value of str, which is not an int.