Program to print all substrings of a given string - c

I am having trouble creating an algorithm that prints all substrings of a given string. This is my implementation now:
#include <stdio.h>
#include <string.h>
// Function to print all sub strings
void subString(char str[], int n)
{
// Pick starting point
for (int len = 1; len <= n; len++)
{
// Pick ending point
for (int i = 0; i <= n - len; i++)
{
// Print characters from current
// starting point to current ending
// point.
int j = i + len - 1;
for (int k = i; k <= j; k++) {
char data[n];
sprintf(data, "%d", str[k]);
printf("%s\n", data);
}
}
}
}
// Driver program to test above function
int main()
{
char str[] = "abc";
subString(str, strlen(str));
return 0;
}
My code is not converting integers to strings. Could someone help me figure out what's wrong?

The logic seems basically fine, but the formatting doesn't make much sense as this prints the digit values for each character and adds a newline for each print call. If you print the characters directly using %c formatting and only print a newline once you've emitted a full substring you'll have a more sensible result.
#include <stdio.h>
#include <string.h>
void subString(char *str, int n)
{
for (int len = 1; len <= n; len++)
{
for (int i = 0; i <= n - len; i++)
{
for (int j = i; j <= i + len - 1; j++)
{
putchar(str[j]);
}
puts("");
}
}
}
int main()
{
char str[] = "abc";
subString(str, strlen(str));
return 0;
}
Output:
a
b
c
ab
bc
abc
A little nitpick: I'd suggest calling this function printSubStrings since it produces a side effect. The name subString doesn't seem to match the contract particularly well.
You can also use the "%.*s" format to extract the substring chunk you want instead of the innermost loop:
void print_substrings(char *str, int n)
{
for (int len = 1; len <= n; len++)
{
for (int i = 0; i <= n - len; i++)
{
printf("%.*s\n", len, str + i);
}
}
}

#include<bits/stdc++.h>
using namespace std;
int main()
{
ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
string str;
cin >> str;
for (int i = 0; i < str.size(); i++) {
for (int len = 1 ; len <= str.size() - i; len++)
{
cout << str.substr(i, len) << endl; // prints substring from starting index i till length len
}
}
return 0;
}
Input:
abcd
Output:
a
ab
abc
abcd
b
bc
bcd
c
cd
d

Related

How to append parts of a string in a char array?

I need to split the string of n size and append in an array.
For example:
input:
abcdefghi
4
output:
[abcd,bcde,cdef,defg,efgh,fghi]
My code giving wrong answer:
#include <stdio.h>
#include <string.h>
int main()
{
char str[] = "abcdefghi";
char result[100];
for(int i=0;i<strlen(str);i++){
strncat(result, str, str[i]+4);
}
printf("result: %s\n ", result);
}
My output:
abcdefgiabcdefgiabcdefgiabcdefgiabcdefgiabcdefgiabcdefgiabcdefgi
What mistake have I made??
Would you please try the following:
#include <stdio.h>
#include <string.h>
int main()
{
char str[] = "abcdefghi";
char result[100];
int n = 4;
int i, j;
char *p = result; // pointer to the string to write the result
*p++ = '['; // left bracket
for (i = 0; i < strlen(str) - n + 1; i++) { // scan over "str"
for (j = i; j < i + n; j++) { // each substrings
*p++ = str[j]; // write the character
}
*p++ = i == strlen(str) - n ? ']' : ','; // write right bracket or a comma
}
*p++ = '\0'; // terminate the string with a null character
printf("result: %s\n", result); // show the result
return 0;
}
Output:
result: [abcd,bcde,cdef,defg,efgh,fghi]
Might this work for you?
#include <stdio.h>
#include <string.h>
int main ()
{
char str[] = "abcdefghijklmno";
char result[100][100];
int nSplit = 4; //Split size
int nLength = strlen (str); //Lenth of the string
int nTotalString = nLength - nSplit; //total possibilities
int nStrCount = 0;
for (int i = 0; i <= nTotalString ; i ++)
{
for (int j = 0; j < nSplit; j++)
result[nStrCount][j] = str[i + j];
nStrCount++;
}
//print array
printf ("result:[");
for (int k = 0; k < nStrCount; k++)
printf ("\"%s\" ", result[k]);
printf ("]");
return 0;
}

Write a C program that sequentially writes two strings into each other?

I got given this assignment:
Write a C program that sequentially writes two strings into each other as shown in the figure below. Start with a string
consisting of “X”-es and with each iteration, the first and last X characters must be rewritten until the entire string is
rewritten and the final message is displayed.
Hint: Make use a function in the library, strlen(), to determine the length of a string.
It should output like this:
XXXXXXXXXXXXXXXXXXXXX
IXXXXXXXXXXXXXXXXXXX!
I XXXXXXXXXXXXXXXXXg!
I lXXXXXXXXXXXXXXXng!
I loXXXXXXXXXXXXXing!
I lovXXXXXXXXXXXming!
I loveXXXXXXXXXmming!
I love XXXXXXXamming!
I love CXXXXXramming!
I love C-XXXgramming!
I love C-PXogramming!
I love C-Programming!
Final String= I love C-Programming!
This is what I have so far:
#include <stdio.h>
#include <string.h>
int main(int argc, char **argv)
{
//data
char str[] = "I love C-Programming!";
int rows;
int columns;
int length = strlen(str);
int format =5;
//process
{
rows = 0;
while (rows <= length)
{
rows++;
}
while (rows > 0)
{
int count = length;
columns = rows - 1;
while (columns > 0)
{
printf("X");
columns--;
count --;
}
if (rows <= length)
{
printf("%.*s", count, str);
}
printf("\n");
rows-=2;
}
printf("%s", str);
}
//output
printf("\n");
printf("\n");
printf("Final String = %s\n", str);
return 0;
}
It doesn't display properly. Please help!
Thanks.
#include <stdio.h>
#include <string.h>
int main()
{
char s1[] = "XXXXXXXXXXXXXXXXXXXXX";
const char s2[] = "I love C-Programming!";
const int n = strlen(s1);
const int h = n / 2;
int i;
int j;
puts(s1);
for (i = 0, j = n - 1; i <= h; ++i, --j) {
s1[i] = s2[i];
s1[j] = s2[j];
puts(s1);
}
return 0;
}
Hi this is indeed a very simple program. Actually your teacher want you to write a program like below:-
int main(int argc, char **argv)
{
//data
char str1[] = "I love C-Programming!";
char str2[strlen(str1)];
memset(str2, 'X', sizeof(str2));//Set all the character to X
str2[strlen(str1)-1]=0;//end of string character value of '\0'
//int rows;
//int columns;
int length = strlen(str1);
//int format =5;
int i = 0;
int j = length - 1;
do
{
printf("%s\n", str2);//Print the second string first
str2[i]=str1[i];//copy from first character from str1
str2[j]=str1[j];//copy from last character from str1
//so in each iteration we are coping two characters from str1 to str2
}while(i++ != j-- );//once I and j are equal break the loop
printf("%s", str2);
/*
//process
{
rows = 0;
while (rows <= length)
{
rows++;
}
while (rows > 0)
{
int count = length;
columns = rows - 1;
while (columns > 0)
{
printf("X");
columns--;
count --;
}
if (rows <= length)
{
printf("%.*s", count, str);
}
printf("\n");
rows-=2;
}
printf("%s", str);
}
*/
//output
printf("\n");
printf("\n");
printf("Final String = %s\n", str2);
return 0;
}
It will out put like below:-
XXXXXXXXXXXXXXXXXXXX
IXXXXXXXXXXXXXXXXXXX!
I XXXXXXXXXXXXXXXXXg!
I lXXXXXXXXXXXXXXXng!
I loXXXXXXXXXXXXXing!
I lovXXXXXXXXXXXming!
I loveXXXXXXXXXmming!
I love XXXXXXXamming!
I love CXXXXXramming!
I love C-XXXgramming!
I love C-PXogramming!
I love C-Programming!
Final String = I love C-Programming!

Runtime Error Message: Line 17: index -3 out of bounds for type 'int [256]'

I need help to understand an issue with my C code. I am trying to find longest substring within a given string without character repetition. When run on the leetcode platform, the code below gives me an error for the String "amqpcsrumjjufpu":
Runtime Error Message: Line 17: index -3 out of bounds for type 'int [256]'
However, the same code works fine when I run it from my computer or any online editor. Please help me to understand this behaviour difference.
#include <stdio.h>
#include <string.h>
int lengthOfLongestSubstring(char* s) {
char *h = s;
int A[256] = {0};
int length = 0;
int temp = 0;
int max = 0;
int len = strlen(s);
for(int i = 0; i < len;i ++){
int A[256] = {0};
length = 0;
h = s + i;
for(int j = i; j < len-1; j++){
if (A[h[j]] == 1) {
break;
} else {
A[h[j]] = 1;
length +=1;
}
if (max < length) {
max = length;
}
}
}
return max;
}
int main() {
char *s = "amqpcsrumjjufpu";
int ret = lengthOfLongestSubstring(s);
printf("SAURABH: %d",ret);
}
It seems you are trying to write a function that finds the length of the longest substring of unique characters.
For starters the function should be declared like
size_t lengthOfLongestSubstring( const char *s );
^^^^^^ ^^^^^
These declarations in the outer scope of the function
int A[256] = {0};
//...
int temp = 0;
are redundant. The variables are not used in the function.
The type char can behave either as the type signed char or the type unsigned char. So in expressions like this A[h[j]] you have to cast explicitly the character used as index to the type unsigned char as for example
A[( unsigned char )h[j]]
The inner loop
for(int j=i;j<len-1;j++){
will not execute for strings that contain only one character. So it does not make sense as it is written.
This if statement
if (max < length) {
max = length ;
}
needs to be placed outside the inner loop.
The algorithm used by you can be implemented the following way
#include <stdio.h>
#include <limits.h>
size_t lengthOfLongestSubstring(const char *s)
{
size_t longest = 0;
for (; *s; ++s )
{
size_t n = 0;
unsigned char letters[UCHAR_MAX] = { 0 };
for ( const char *p = s; *p && !letters[(unsigned char)*p - 1]++; ++p) ++n;
if (longest < n) longest = n;
}
return longest;
}
int main( void )
{
char *s = "123145";
printf("The longest substring has %zu characters.\n",
lengthOfLongestSubstring(s));
return 0;
}
The program output is
The longest substring has 5 characters.
Your code crashed because you read data out of range, suppose your input string is amqpcsrumjjufpu its length is 15, in outer loop for i = 13 you do assigment
h = s + i; // h was updated to indicate to 13th element of s
and in inner loop for first iteration, you read this element (j == i == 13)
A[h[j]]
so, you try to read this element A[*(h+j)], but h indicates to 13th element of s, and now you try to add 13 to this value, you want to read 26th position of s, you are out of range of s string.
Thanks Everyone for responses. While Vlad's code worked for all the test cases, here is my code that also passed all the test cases after changes suggested by Vlad and rafix.
int lengthOfLongestSubstring(char* s) {
char *h = s;
int max = 0;
int len = strlen(s);
if (len == 1) {
return 1;
}
for(int i = 0; i < len;i ++){
int A[256] = {0};
int length = 0;
for(int j = i; j < len; j++){
if (A[(unsigned char)h[j]] == 1) {
break;
} else {
A[(unsigned char) h[j]] = 1;
length +=1;
}
}
if (max < length) {
max = length;
}
}
return max;
}

String array prints out trash values

So I have an assignment where I should delete a character if it has duplicates in a string. Right now it does that but also prints out trash values at the end. Im not sure why it does that, so any help would be nice.
Also im not sure how I should print out the length of the new string.
This is my main.c file:
#include <stdio.h>
#include <string.h>
#include "functions.h"
int main() {
char string[256];
int length;
printf("Enter char array size of string(counting with backslash 0): \n");
/*
Example: The word aabc will get a size of 5.
a = 0
a = 1
b = 2
c = 3
/0 = 4
Total 5 slots to allocate */
scanf("%d", &length);
printf("Enter string you wish to remove duplicates from: \n");
for (int i = 0; i < length; i++)
{
scanf("%c", &string[i]);
}
deleteDuplicates(string, length);
//String output after removing duplicates. Prints out trash values!
for (int i = 0; i < length; i++) {
printf("%c", string[i]);
}
//Length of new string. The length is also wrong!
printf("\tLength: %d\n", length);
printf("\n\n");
getchar();
return 0;
}
The output from the printf("%c", string[i]); prints out trash values at the end of the string which is not correct.
The deleteDuplicates function looks like this in the functions.c file:
void deleteDuplicates(char string[], int length)
{
for (int i = 0; i < length; i++)
{
for (int j = i + 1; j < length;)
{
if (string[j] == string[i])
{
for (int k = j; k < length; k++)
{
string[k] = string[k + 1];
}
length--;
}
else
{
j++;
}
}
}
}
There is a more efficent and secure way to do the exercise:
#include <stdio.h>
#include <string.h>
void deleteDuplicates(char string[], int *length)
{
int p = 1; //current
int f = 0; //flag found
for (int i = 1; i < *length; i++)
{
f = 0;
for (int j = 0; j < i; j++)
{
if (string[j] == string[i])
{
f = 1;
break;
}
}
if (!f)
string[p++] = string[i];
}
string[p] = '\0';
*length = p;
}
int main() {
char aux[100] = "asdñkzzcvjhasdkljjh";
int l = strlen(aux);
deleteDuplicates(aux, &l);
printf("result: %s -> %d", aux, l);
}
You can see the results here:
http://codepad.org/wECjIonL
Or even a more refined way can be found here:
http://codepad.org/BXksElIG
Functions in C are pass by value by default, not pass by reference. So your deleteDuplicates function is not modifying the length in your main function. If you modify your function to pass by reference, your length will be modified.
Here's an example using your code.
The function call would be:
deleteDuplicates(string, &length);
The function would be:
void deleteDuplicates(char string[], int *length)
{
for (int i = 0; i < *length; i++)
{
for (int j = i + 1; j < *length;)
{
if (string[j] == string[i])
{
for (int k = j; k < *length; k++)
{
string[k] = string[k + 1];
}
*length--;
}
else
{
j++;
}
}
}
}
You can achieve an O(n) solution by hashing the characters in an array.
However, the other answers posted will help you solve your current problem in your code. I decided to show you a more efficient way to do this.
You can create a hash array like this:
int hashing[256] = {0};
Which sets all the values to be 0 in the array. Then you can check if the slot has a 0, which means that the character has not been visited. Everytime 0 is found, add the character to the string, and mark that slot as 1. This guarantees that no duplicate characters can be added, as they are only added if a 0 is found.
This is a common algorithm that is used everywhere, and it will help make your code more efficient.
Also it is better to use fgets for reading input from user, instead of scanf().
Here is some modified code I wrote a while ago which shows this idea of hashing:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define NUMCHAR 256
char *remove_dups(char *string);
int main(void) {
char string[NUMCHAR], temp;
char *result;
size_t len, i;
int ch;
printf("Enter char array size of string(counting with backslash 0): \n");
if (scanf("%zu", &len) != 1) {
printf("invalid length entered\n");
exit(EXIT_FAILURE);
}
ch = getchar();
while (ch != '\n' && ch != EOF);
if (len >= NUMCHAR) {
printf("Length specified is longer than buffer size of %d\n", NUMCHAR);
exit(EXIT_FAILURE);
}
printf("Enter string you wish to remove duplicates from: \n");
for (i = 0; i < len; i++) {
if (scanf("%c", &temp) != 1) {
printf("invalid character entered\n");
exit(EXIT_FAILURE);
}
if (isspace(temp)) {
break;
}
string[i] = temp;
}
string[i] = '\0';
printf("Original string: %s Length: %zu\n", string, strlen(string));
result = remove_dups(string);
printf("Duplicates removed: %s Length: %zu\n", result, strlen(result));
return 0;
}
char *remove_dups(char *str) {
int hash[NUMCHAR] = {0};
size_t count = 0, i;
char temp;
for (i = 0; str[i]; i++) {
temp = str[i];
if (hash[(unsigned char)temp] == 0) {
hash[(unsigned char)temp] = 1;
str[count++] = str[i];
}
}
str[count] = '\0';
return str;
}
Example input:
Enter char array size of string(counting with backslash 0):
20
Enter string you wish to remove duplicates from:
hellotherefriend
Output:
Original string: hellotherefriend Length: 16
Duplicates removed: helotrfind Length: 10

Counting characters in a string or file

I have the following code:
#include "stdafx.h"
#include "string.h"
#include "ctype.h"
/*selection sort*/
void swap(int A[], int j, int k)
{
int p = A[k];
int i;
for (i = 0; i < (k - j); i++)
{
A[k - i] = A[k - i - 1];
}
A[j] = p;
}
/*greatest number in an array*/
int max(int A[], int N, int k)
{
int max = k, i;
for (i = k; i < N; i++)
{
if (A[max] < A[i])
max = i;
}
return max;
}
int count_nonspace(const char* str)
{
int count = 0;
while(*str)
{
if(!isspace(*str++))
count++;
}
return count;
}
int _tmain(int argc, _TCHAR* argv[])
{
int a[256];
int i = 0, j = 0, count[256] = { 0 };
char string[100] = "Hello world";
for (i = 0; i < 100; i++)
{
for (j = 0; j<256; j++)
{
if (tolower(string[i]) == (j))
{
count[j]++;
}
}
}
for (j = 0; j<256; j++)
{
printf("\n%c -> %d \n", j, count[j]);
}
}
Program is calculating the number of apperances of each character in a string. Now it prints the number of apperances of all 256 characters, whereas i want it to prinf only the character with greatest number of apperances in a string. My idea was to use the selection sort method to the array with the nubmer of apperances, but this is not working, thus my question is how to printf only the character with the greatest number of apperances in the string?
If anybody would have doubts, this is NOT my homework question.
EDIT: I've just noticed that this code printf apperances of characters begining with "j" why is that?
I started typing this before the others showed up, so I'll post it anyway. This is probably nearly the most efficient (increasing efficiency would add some clutter) way of getting an answer, but it doesn't include code to ignore spaces, count characters without regard to case, etc (easy modifications).
most_frequent(const char * str)
{
unsigned counts[256];
unsigned char * cur;
unsigned pos, max;
/* set all counts to zero */
memset(counts, 0, sizeof(counts));
/* count occurences of each character */
for (cur = (unsigned char *)str; *cur; ++cur)
++counts[*cur];
/* find most frequent character */
for (max = 0, pos = 1; pos < 256; ++pos)
if ( counts[pos] > counts[max] )
max = pos;
printf("Character %c occurs %u times.\n", max, counts[max]);
}
Create an array with your char as index.
Keep incrementing the value in the array based on the characters read.
Now get the max out of the array which gives you the most occurring char in your input.
Code will look like:
#include <stdio.h>
#include<string.h>
#include<stdlib.h>
int main(void) {
char buf[100];
int i=0,max =0,t=0;
int a[256];
memset(a,0,sizeof(a));
fgets(buf,100,stdin);
buf[strlen(buf)-1] = '\0';
while(buf[i] != '\0')
{
a[(int)buf[i]]++;
i++;
}
i=0;
for(i=0;i<256;i++)
{
if(a[i] > max)
{
max = a[i];
t = i;
}
}
printf("The most occurring character is %c: Times: %d",t,max);
return 0;
}
Here is a solution for that, based on your own solution, and using qsort().
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
struct Frequency
{
int character;
int count;
};
int compare(const void *const lhs, const void *const rhs)
{
return ((struct Frequency *)rhs)->count - ((struct Frequency *)lhs)->count;
}
int main(int argc, char* argv[])
{
int i = 0, j = 0;
struct Frequency count[256];
memset(&count, 0, sizeof(count));
char string[100] = "Hello world";
for (i = 0 ; i < 100 ; i++)
{
for (j = 0 ; j < 256 ; j++)
{
count[j].character = j;
if (tolower(string[i]) == j)
{
count[j].count += 1;
}
}
}
qsort(count, sizeof(count) / sizeof(*count), sizeof(*count), compare);
/* skip the '\0' which was counted many times */
if (isprint(count[1].character))
printf("\nThe most popular character is: %c\n", count[1].character);
else
printf("\nThe most popular character is: \\%03x\n", count[1].character);
for (j = 0 ; j < 256 ; j++)
{
if (isprint(count[j].character))
printf("\n%c -> %d \n", count[j].character, count[j].count);
else
printf("\n\\%03x -> %d \n", count[j].character, count[j].count);
}
}
notice that the '\0' is set for all the remainig bytes in
char string[100] = "Hello world";
so the count of '\0' will be the highest.
You could use strlen() to skip '\0', in the counting loop, but don't
for (i = 0 ; i < strlen(string) ; ++i) ...
do it this way
size_t length = strlen(string);
for (i = 0 ; i < length ; ++i) ...

Resources