This is the question I'm working on : http://www.geeksforgeeks.org/recursively-remove-adjacent-duplicates-given-string/
Here's my code in Java for one pass :
/*If a character isn't repeating, copy it to str[j].
* Find start and end indices of repeating characters. Recursively call again
* And starting position now should be end+1. Pass j and starting position */
public class removeDuplicates {
public static void main(String[] args)
{
char[] str = {'c','c'};
removeDups(str,0,0,0);
System.out.println(str);
}
public static void removeDups(char[] str,int j, int start,int flag)
{
/*Check if start character is repeating or not. If yes , then loop till you find
* another character. Pass that characters index(new start) into a recursive call*/
if(start == str.length-1)
{
if(flag!=1)
{
str[j] = str[start];
j++;
}
if(j<=str.length-1)
{
str[j] = '0';
}
}
while(start<str.length-1 && str[start]!='0')
{
if(str[start+1]!=str[start])
{
str[j] = str[start];
start++;
j++;
if(start==str.length-1) {removeDups(str,j,start,flag);}
}
else
{
char ref = str[start];
while(str[start]==ref)
{
if(start<str.length-1)
{
start++;
}
else
{
flag =1;
break;
}
}
removeDups(str,j,start,flag);
return;
}
}
}
}
This works as expected. Here I'm just trying to use a 0 instead of \0 character as in C. Now when I translate the code to C
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
void removeDups(char *str,int j, int start,int flag)
{
/*Check if start character is repeating or not. If yes , then loop till you find
* another character. Pass that characters index(new start) into a recursive call*/
if(start == strlen(str)-1)
{
if(flag!=1)
{
str[j] = str[start];
j++;
}
if(j<=strlen(str)-1)
{
str[j] = '\0';
}
}
while(start<strlen(str)-1 && str[start]!='0')
{
if(str[start+1]!=str[start])
{
str[j] = str[start];
start++;
j++;
if(start==strlen(str)-1) {removeDups(str,j,start,flag);}
}
else
{
char ref = str[start];
while(str[start]==ref)
{
if(start<strlen(str)-1)
{
start++;
}
else
{
flag =1;
break;
}
}
removeDups(str,j,start,flag);
return;
}
}
}
int main()
{
char str[] = "abcddcba";
int len =
while()
for(int i=0;str[i]!='\0';i++)
{
printf("%c",str[i]);
}
printf("\n");
}
The above code gives different results as compared to the Java code.Its virtually identical , just that I'm using strlen() instead of str.length(as in Java).
The interesting part is : if I change the portion to
if(j<=strlen(str)-1)
{
str[j] = '\0';
return;
}
it works perfectly. I've just added a return statement to the if statement.
Why is this happening ? Identical code producing different results in C and Java
You are using return statement and subsequently all code below that return is being excluded from running for that iteration.
Also, You may want to understand what is \0 is and how it's different than 0.
Here's link:
What does the \0 symbol mean in a C string?
In C, assigning a character in a string to '\0' changes the length, so strlen() will return a different result after that. In your Java code, you're using an array, and an array length never changes. You're setting the character to '0' instead of '\0', which are two different things, but even if you did set it to '\0', it still wouldn't change the length. I haven't examined your entire code, but this is one obvious thing that would cause different results.
Related
So right now my code checks if the sub string is present in the code and returns true or false, I would like to find where these substrings are located in the total string. how can you implement that.
#include <stdio.h>
#include <stdbool.h>
bool checksub(const char *strng,const char *subs){
if (*strng=='\0' && *subs!='\0'){
return false;
}
if (*subs=='\0'){
return true;}
if (*strng==*subs){
return checksub(strng+1,subs+1);
}
return false;
}
bool lsub(char *strng,char *subs){
if (*strng=='\0'){
return false;
}
if (*strng==*subs){
if (checksub(strng,subs)){
return 1;
}
}
return lsub(strng+1,subs);
}
int main(){
printf("%d\n",checksub("ababuu","ab"));
printf("%d\n",checksub("the bed bug bites","bit"));
return 0;
}
First you should get rid of recursion since it's often slow and dangerous, for nothing gained.
A (naive) version of strstr that returns an index rather than a pointer might look like this:
int strstr_index (const char* original, const char* sub)
{
int index = -1;
for(const char* str=original; *str!='\0' && index==-1; str++)
{
for(size_t i=0; str[i]==sub[i] && str[i]!='\0'; i++)
{
if(sub[i+1] == '\0')
{
index = (int)(str - original);
break;
}
}
}
return index;
}
This returns -1 if not found, otherwise an index.
It iterates across the string one character at a time.
When a character match with the sub string is found, it starts executing the inner loop as well.
If the inner loop continues to find matches all the way to the end of the sub string, then we found a match.
The index can be obtained by pointer arithmetic: the start address of the found sub string minus the start of the string. The result of that subtraction is strictly speaking a special integer type called ptrdiff_t, but I used int to simplify the example.
I'm trying to print an array of structs that contain two strings. However my print function does not print more than two indices of the array. I am not sure why because it seems to me that the logic is correct.
This is the main function
const int MAX_LENGTH = 1024;
typedef struct song
{
char songName[MAX_LENGTH];
char artist[MAX_LENGTH];
} Song;
void getStringFromUserInput(char s[], int maxStrLength);
void printMusicLibrary(Song library[], int librarySize);
void printMusicLibraryTitle(void);
void printMusicLibrary (Song library[], int librarySize);
void printMusicLibraryEmpty(void);
int main(void) {
// Announce the start of the program
printf("%s", "Personal Music Library.\n\n");
printf("%s", "Commands are I (insert), S (sort by artist),\n"
"P (print), Q (quit).\n");
char response;
char input[MAX_LENGTH + 1];
int index = 0;
do {
printf("\nCommand?: ");
getStringFromUserInput(input, MAX_LENGTH);
// Response is the first character entered by user.
// Convert to uppercase to simplify later comparisons.
response = toupper(input[0]);
const int MAX_LIBRARY_SIZE = 100;
Song Library[MAX_LIBRARY_SIZE];
if (response == 'I') {
printf("Song name: ");
getStringFromUserInput(Library[index].songName, MAX_LENGTH);
printf("Artist: ");
getStringFromUserInput(Library[index].artist, MAX_LENGTH);
index++;
}
else if (response == 'P') {
// Print the music library.
int firstIndex = 0;
if (Library[firstIndex].songName[firstIndex] == '\0') {
printMusicLibraryEmpty();
} else {
printMusicLibraryTitle();
printMusicLibrary(Library, MAX_LIBRARY_SIZE);
}
This is my printing the library function
// This function will print the music library
void printMusicLibrary (Song library[], int librarySize) {
printf("\n");
bool empty = true;
for (int i = 0; (i < librarySize) && (!empty); i ++) {
empty = false;
if (library[i].songName[i] != '\0') {
printf("%s\n", library[i].songName);
printf("%s\n", library[i].artist);
printf("\n");
} else {
empty = true;
}
}
}
I think the problem is caused due to setting : empty = true outside the for loop and then checking (!empty) which will evaluate to false. What I am surprised by is how is it printing even two indices. You should set empty = false as you are already checking for the first index before the function call.
The logic has two ways to terminate the listing: 1) if the number of entries is reached, or 2) if any entry is empty.
I expect the second condition is stopping the listing before you expect. Probably the array wasn't built as expected (I didn't look at that part), or something is overwriting an early or middle entry.
you gave the definition as:
typedef struct song
{
char songName[MAX_LENGTH];
char artist[MAX_LENGTH];
}Song;
the later, you write if (library[i].songName[i] != '\0') which really seems strange: why would you index the songname string with the same index that the lib?
so I would naturally expect your print function to be:
// This function will print the music library
void printMusicLibrary (Song library[], int librarySize) {
for (int i = 0; i < librarySize; i ++) {
printf("%s\n%s\n\n", library[i].songName,
library[i].artist);
}
}
note that you may skip empty song names by testing library[i].songName[0] != '\0' (pay attention to the 0), but I think it would be better not to add them in the list (does an empty song name make sens?)
(If you decide to fix that, note that you have an other fishy place: if (Library[firstIndex].songName[firstIndex] == '\0') with the same pattern)
i'm making a small test to see if a word is inside another, and i want to return the index where that word begins.
Example: if i check "um" inside "amolum" the return value should be 4(position of the leter "u" where the word begins.
This is what my code looks like:
(...)
int cad_look_str (char s1[], char s2[]) {
int indS1 = 0, indS2 = 0;
while (s1[indS1]!='\0'|| s2[indS2]!='\0') {
if (s1[indS1]==s2[indS2]) {
indS1++;
indS2++;
}
else indS1=0;
}
if (s2[indS2]=='\0' && s1[indS1]!='\0') return -1;
else return indS2-strlen (s1);
}
void main () {
char s[100];
char s1[100];
scanf ("%s",s);
scanf ("%s",s1);
printf ("%d \n", cad_look_str(s1,s) );
}
The problem is that when i compile this, it doesn't stop looping on scanf... It just continues to ask for strings.
If i put cad_look_str(s1,s1) on the last line, it works fine... Why is this happening?
Regards
Your initial loop condition will never terminate if the first characters don't match your comparison test within your if statement.
The 'while' loop checks to ensure the current character positions (both 0 on first pass) are non-terminators. If they're not, and they're not equal, indS1 is reset to its starting position. indS2 never changes, thus the while condition is unchanged.
Might look at some other string functions to accomplish your task unless the scanning is a mandatory component for some reason.
Index of second string should be incremented in the else part also.
if (s1[indS1]==s2[indS2])
{
indS1++; indS2++;
}
else {
indS1=0;
indS2++;
}
changed cad_look_str() for situations like s1 : gdgddadada, s2 : dadada
int cad_look_str (char s1[], char s2[]) {
int indS1 = 0, indS2 = 0;
int flag = 0;
while (s1[indS1]!='\0'&& s2[indS2]!='\0') {
if (s1[indS1]==s2[indS2]) {
indS1++;
indS2++;
flag = 1;
}
else
{
indS1=0;
indS2++;
if(flag) indS2--; // to work with srtrings s1: gdgddadada s2: dadada
flag = 0;
}
}
if (s2[indS2]=='\0' && s1[indS1]!='\0') return -1;
else return indS2-strlen (s1);
}
//Function to store select_field
void store_field(int num_fields, unsigned long *lengths,
MYSQL_ROW row, char elect_type[10][100])
{
//Storing select_field below
int i,j,k,g;
for( i=1;i < num_fields;i=i+10)
{
// i+10 so that loop is executed one time only,
// i=1 bcoz 2nd entry is select_type
for (j=0;j<lengths[i];j++)
{
if (row[i] != NULL)
{
select_type[k][j] = *row[i];
row[i]++;
}
if (row[i] == NULL)
{
select_type[k][j]= '\0';
printf ( "NULL\n");
break; // row[i] is null for fields containing NULL
}
}
for (j;j<100;j++)
{
select_type[k][j]='\0';
}
// setting every other empty field in current row
// of select_type to NULL
}
k++;
}
g = k; //HERE I AM GETTING THE ERROR
for (k;k<10;k++){for(j=0;j<100;j++)
{
select_type[k][j]='\0';
}
}
I have already declared k in the function but I am getting the error.
If you get "not in a function", that means that the code being flagged is, wait for it, not in a function.
Probably a mis-matched closing brace (}) that causes your function to end before you think it does.
I gave up on re-formatting your code to find the problem.
You've got an extra closing bracket. The line
} g=k; **//HERE I AM GETTING THE ERROR**
closes the function.
I took the liberty of formatting out the code indentation. If you maintain good indentation it should be clear that the } is out of place:
#include <stdio.h>
#include <ctype.h> // For tolower() function //
//Function to store select_field
void store_field(int num_fields,unsigned long *lengths,MYSQL_ROW row,char select_type[10][100]){
//Storing select_field below
int i,j,k,g;
for( i=1;i < num_fields;i=i+10){ // i+10 so that loop is executed one time only , i=1 bcoz 2nd entry is select_type
for (j=0;j<lengths[i];j++){
if (row[i] != NULL){ select_type[k][j] = *row[i];
row[i]++;
}
if (row[i] == NULL) { select_type[k][j]= '\0'; printf ( "NULL\n");break; // row[i] is null for fields containing NULL
}
}for (j;j<100;j++){select_type[k][j]='\0';} //setting every other empty field in current row of select_type to NULL
} k++;
// } g=k; **//HERE I AM GETTING THE ERROR**
for (k;k<10;k++){for(j=0;j<100;j++){select_type[k][j]='\0'; }}
}
You should always indent your code to avoid this kind of error. You can find different indentation styles, choose the one you like the most
http://en.wikipedia.org/wiki/Indent_style
There are also automatic indentation tools, below is your code correctly indented
void store_field(int num_fields,unsigned long *lengths,MYSQL_ROW row,char select_type[10][100])
{
int i,j,k,g;
for( i=1;i < num_fields;i=i+10)
{
for (j=0;j<lengths[i];j++)
{
if (row[i] != NULL)
{
select_type[k][j] = *row[i];
row[i]++;
}
if (row[i] == NULL)
{
select_type[k][j]= '\0';
printf ( "NULL\n");
break; // row[i] is null for fields containing NULL
}
}
for (j;j<100;j++)
{
select_type[k][j]='\0';
}
}
k++;
}
g=k; **//HERE I AM GETTING THE ERROR**
for (k;k<10;k++){for(j=0;j<100;j++)
{
select_type[k][j]='\0';
}
}
}
All the errors and extra brackets become evident immediately. Check for some code style guides, there many, choose one you like and stick to that one.
#include<stdio.h>
char *removedps(char *x)
{
int Ar[256] = {0};
int ip=0;
int op=0;
char temp;
while(*(x+ip))
{
temp = (*(x+ip));
if (!Ar[temp]) {
Ar[temp] = 1;
*(x+ip) = *(x+op);
op++;
}
ip++;
*(x+op) = '\0';
}
return x;
}
int main()
{
char lo[] = "0001";
printf("%s",removedps(lo));
}
My code is not working
I have tried hard to see the error
All I GET IS the first character .
My idea is simple
make an array of 256 places
insert Zero into them
Then insert 1 for each character inside the string (on that position of the array)
your assignment looks to be the error here.
op is "out postiion", ip is "in position"
so it should be
*(x+op) = *(x+ip);
not the other way.
because *(x+op) = '\0';
is always run every iteration of the loop.
I'd probablly do it more like this ( using your method, which I probablly wouldn't use personally)
char *removedps(char *x)
{
int Ar[256] = {0};
char* start = x;
while(*x)
{
if (Ar[*x])
{ // remove the repeated character
memmove(x, x+1, strlen(x));
}
else
{
Ar[*x] = 1;
x++;
}
}
return start;
}
also, I'd name it remove_duplicate_chars or something, not a fan of cryptic abbreviations.
At the end of the loop, you do *(x+op)='\0';, and then, in the next iteration, you do *(x+ip)=*(x+op);, so from the 2sd iteration, you put there 0.
try do something like:
for (op=ip=0;x[ip];ip++) {
if (!Ar[x[ip]]++) x[op++]=x[ip];
}
x[op]=0;