C + + string processing problem

Posted by powerpants on Sat, 05 Mar 2022 01:48:14 +0100

1, Title

1.1 Title picture

1.2 Title Document

#include <iostream>
#include <ctime>

using namespace std;

//Define a type def that will be very useful when we implement our functions.
typedef char* charPointer;
//This type def will make cstring parameter passing by reference easy to debug
//Example void foo(charPointer& x) is easier to debug than void foo(char* & x)

int main()
{
	/*
	This program is designed to test the functions you need to implement.
	You should NOT remove any line of code from this test program.
	But you may add more test code in the program if you like.
	*/
	cout << "This program is designed to help you test your functions." << endl;
	srand(time(0));

	//Test cstrlen function
	//The function must return the number of printable characters of a cstring argument
	cout << endl << "Testing cstrlen function";
	cout << endl << "------------------------" << endl;
	char s1[] = "irregular";
	cout << "The length of \"" << s1 << "\" is " << cstrlen(s1) << endl;
	cout << "The length of \"\" is " << cstrlen("") << endl;

	//Test countChars function
	//The function must return the number of times a character argument is found in a cstring argument
	cout << endl << "Testing countChars function";
	cout << endl << "---------------------------" << endl;
	char ch = rand() % 26 + 97;
	int count = countChars(s1, ch);
	cout << "'" << ch << "' is found in \"" << s1 << "\" " << count << " times." << endl; 

	//Test isFound function
	//The function must return true if a character argument is found in a cstring argument in the index interval [a, b)
	//The integer arguments a and b are optional arguments. If they are not suplied, then the function uses
	//the values a = 0 and b = the length of the cstring argument
	//The function must return false if the character argument is not found in the cstring argument in the interval [a, b)
	cout << endl << "Testing isFound function";
	cout << endl << "-------------------------" << endl;
	int a = 2, b = cstrlen(s1);
	ch = rand() % 26 + 97;
	bool flag = isFound(s1, ch, a, b);
	if (flag)
		cout << "'" << ch << "' is found in \"" << s1 << "\" in the index interval [" << a << ", " << b << ") " << endl;
	else
		cout << "'" << ch << "' is not found in \"" << s1 << "\" in the index interval [" << a << ", " << b << ") " << endl;

	a = 3;
	ch = rand() % 26 + 97;
	flag = isFound(s1, ch, a);
	if (flag)
		cout << "'" << ch << "' is found in \"" << s1 << "\" in the index interval [" << a << ", " << b << ") " << endl;
	else
		cout << "'" << ch << "' is not found in \"" << s1 << "\" in the index interval [" << a << ", " << b << ") " << endl;

	b = 8;
	ch = rand() % 26 + 97;
	flag = isFound(s1, ch, a, b);
	if (flag)
		cout << "'" << ch << "' is found in \"" << s1 << "\" in the index interval [" << a << ", " << b << ") " << endl;
	else
		cout << "'" << ch << "' is not found in \"" << s1 << "\" in the index interval [" << a << ", " << b << ") " << endl;

	//Test cstringCopy function
	//Function signature: cstringCopy(destination, source)
	//The function must copy the source cstring to the destination cstring
	//The function must first delete the memory allocated for destination cstring and then
	//allocate enough memory to perform the copying without any index out of bounds error
	//Remark: You need to pass the destination cstring argument by reference. Thus the function
	//signature should be something like: void cstringCopy(charPointer& destination, const charPointer& source)
	cout << endl << "Testing cstringCopy function";
	cout << endl << "------------------------" << endl;
	char* s2 = new char('\0');
	cstringCopy(s2, "irregular");
	cout << "A copy of \"irregular\" is \"" << s2 << "\"" << endl;

	char* s3 = new char('\0');
	cstringCopy(s3, s2);
	cout << "A copy of \"" << s2 << "\" is \"" << s3 << "\"" << endl;

	delete[] s2;
	s2 = new char('\0');
	cout << "s2 is modified to \"" << s2 << "\" but s3 is still \"" << s3 << "\"" << endl;

	delete[] s3;
	s3 = new char('\0');
	cstringCopy(s3, s2);
	cout << "A copy of \"" << s2 << "\" is \"" << s3 << "\"" << endl;

	//Test rotateString function
	//The function must rotate the characters of of its cstring argument by r units
		//If r > 0, rotate the characters of the argument to the left
		//If r < 0, rotate the characters of the argument to the right
		//Please note the value of r can be any integer including larger than the length of s
		//For example,
			//"asmara" rotated to the left by 0 becomes "asmara"
			//"asmara" rotated to the left by 1 becomes "smaraa"
			//"asmara" rotated to the left by 2 becomes "maraas"
		//similarly
			//"asmara" rotated to the right by 0 becomes "asmara"
			//"asmara" rotated to the right by 1 becomes "aasmar"
			//"asmara" rotated to the right by 2 becomes "raasma"

	cout << endl << "Testing rotateString function";
	cout << endl << "-----------------------------" << endl;
	char s4[] = "asmara";
	for (int i = 0; i < 10; i++)
	{
		int r = rand() % 101 - 50;
		if (r > 0)
			cout << "\"" << s4 << "\" rotated " << r << " times to the left becomes ";
		else
			cout << "\"" << s4 << "\" rotated " << -r << " times to the right becomes ";
		rotateString(s4, r);
		cout << "\"" << s4 << "\"" << endl;
	}

	//Test append character function
	//The function must concatenate the character argument to the cstring argument.
	//Hint: Parameter passing by reference is needed
	cout << endl << "Testing append character function";
	cout << endl << "---------------------------------" << endl;
	char* s5 = new char('\0');
	for (int i = 0; i < 20; i++)
	{
		ch = rand() % 26 + 97;
		cout << "Appending '" << ch << "' to \"" << s5 << "\" gives \"";
		append(s5, ch);
		cout << s5 << "\"" << endl;
	}

	//Test append cstring function
	//Function signature: append(destination, source)
	//The function must append all the characters of source cstring to the destination cstring
	//The function must not modify the source cstring
	//Hint: Make use of your append character function when you implement this function
	//Hint: Parameter passing by reference is needed
	cout << endl << "Testing append cstring function";
	cout << endl << "-------------------------------" << endl;
	char* s6 = new char('\0');
	cout << "Appending \"" << s5 << "\" to \"" << s6 << "\" gives \"";
	append(s6, s5);
	cout << s6 << "\"" << endl;

	//Test removeChar function
	//The function must remove the first character of the cstring argument that is equal to the character argument
	//Then the function must return true if it has found a character and removed it; otherwise returns false
	//Hint: Parameter passing by reference is needed
	cout << endl << "Testing removeChar function";
	cout << endl << "---------------------------" << endl;
	char* s7 = new char[11];
	for (int i = 0; i < 10; i++)
		s7[i] = rand() % 26 + 97;
	s7[10] = '\0';
	for (int i = 0; i < 20; i++)
	{
		ch = rand() % 26 + 97;
		cout << "Removing '" << ch << "' from \"" << s7 << "\" gives \"";
		removeChar(s7, ch);
		cout << s7 << "\"" << endl;
	}

	//Test removeCharAll function
	//The function must remove all characters of the cstring argument that are equal to the character argument
	//Hint: Use your removeChar function when you implement this function
	cout << endl << "Testing removeCharAll function";
	cout << endl << "------------------------------" << endl;
	char* s8 = new char[11];
	for (int i = 0; i < 10; i++)
		s8[i] = rand() % 3 + 97;
	s8[10] = '\0';
	ch = rand() % 3 + 97;
	cout << "Removing all occurences of '" << ch << "' from \"" << s8 << "\" gives \"";
	removeCharAll(s8, ch);
	cout << s8 << "\"" << endl;

	//Test isEqual function
	//The function must return true if the two cstring arguments have equal length and their characters at
	//the same indexes are equal. Otherwise return false.
	cout << endl << "Testing isEqual function";
	cout << endl << "------------------------" << endl;
	char s9[] = "yonas";
	char s10[] = "yonas";
	if (isEqual(s9, s10))
		cout << "\"" << s9 << "\" and \"" << s10 << "\" are equal" << endl;
	else
		cout << "\"" << s9 << "\" and \"" << s10 << "\" are not equal" << endl;
	if (isEqual("CMPT130", "CMPT135"))
		cout << "CMPT130 and CMPT135 are equal" << endl;
	else
		cout << "CMPT130 and CMPT135 are not equal" << endl;

	//Test isAnagram function
	//The function must return true if the two cstring arguments are anagrams of each other.
	//Otherwise return false
	//Definition: Two cstrings are anagrams of each other if every character of one cstring is found 
	//in the other cstring and that the number of times the character appears in both cstrings are equal
	cout << endl << "Testing isAnagram function";
	cout << endl << "--------------------------" << endl;
	if (isAnagram("massachussettes", "tessetsuchmassa") == true)
		cout << "massachussettes and tessetsuchmassa are anagrams" << endl;
	else
		cout << "massachussettes and tessetsuchmassa are not anagrams" << endl;
	if (isAnagram("CMPT130", "CMPT135") == true)
		cout << "CMPT130 and CMPT135 are anagrams" << endl;
	else
		cout << "CMPT130 and CMPT135 are not anagrams" << endl;

	//Test zigzagMerge function
	//Function signature: zigzagMerge(cstring1, cstring2)
	//The function must return a new cstring by merging (combining) the characters of cstring1 and cstring2 in zigzag form. 
		//That is 
			//The first character of the new cstring is the first character of cstring1
			//The second character of the new cstring is the first character of cstring2
			//The third character of the new cstring is the second character of cstring1
			//The fourth character of the new cstring is the second character of cstring2
			//The fifth character of the new cstring is the third character of cstring1
			//The sixth character of the new cstring is the third character of cstring2
			//etc
		//When either cstring1 or cstring2 reaches to its end, the remaining characters of the other are 
		//appended to the new cstring
		//For example, the zigzagMerge of "abc" and "12345" will be "a1b2c345"
	cout << endl << "Testing zigzagMerge function";
	cout << endl << "----------------------------" << endl;
	char* s11 = zigzagMerge("cmpt130", "123");
	cout << "The zigzag merge of \"cmpt130\" and \"123\" is \"" << s11 << "\"" << endl;

	//Test getSubString function
	//Function signature: getSubString(cstring, startIndex, length)
	//The function must return a new cstring made from the characters of the cstring argument starting from
	//the startIndex argument and containing as many as the length argument characters.
	//If the cstring argument has fewer characters starting from the startIndex upto its last character, 
	//then this function must return a substring consisting of only the available characters starting from 
	//the startIndex upto its last character. In this case, the returned substring will have less than length characters.
	cout << endl << "Testing getSubString function";
	cout << endl << "-----------------------------" << endl;
	char s12[] = "irresponsible";
	for (int i = 0; i < 5; i++)
	{
		int index = rand() % cstrlen(s1);
		int len = rand() % cstrlen(s1) + 1;
		char* s13 = getSubString(s12, index, len);
		cout << "A substring of \"" << s12 << "\" starting from index " << index << " with " << len << " characters is ";
		cout << "\"" << s13 << "\"" << endl;
		delete[] s13;
	}

	//Test isSubString function
	//Function signature: isSubString(cstring1, cstring2)
	//This function must return true if cstring1 argument is a substring of cstring2 argument.
	//Otherwise returns false.
	//Definition: cstring1 is a substring of cstring2 if there exist valid integers startIndex and length such that
	//the function call getSubString(cstring2, startIndex, length) returns a cstring that is equal to cstring1.
	cout << endl << "Testing isSubString function";
	cout << endl << "----------------------------" << endl;
	if (isSubString("set", "massachussettes"))
		cout << "\"set\" is a substring of \"massachussettes\"" << endl;
	else
		cout << "\"set\" is not a substring of \"massachussettes\"" << endl;

	if (isSubString("", "c"))
		cout << "\"\" is a substring of \"c\"" << endl;
	else
		cout << "\"\" is not a substring of \"c\"" << endl;

	if (isSubString("test", "massachussettes"))
		cout << "\"test\" is a substring of \"massachussettes\"" << endl;
	else
		cout << "\"test\" is not a substring of \"massachussettes\"" << endl;

	//Test countWords function
	//This function must return the number of words contained in a cstring argument.
		//Here, a word means some characters with no any spaces in between.
		//Example: If the cstring argument is "What    a     nice           problem "
		//Then you see that there are FOUR words in this cstring, namely
		//     1. What      2. a       3. nice      4. problem
		//Thus your function then must return 4

		//Please note that,
		//1. There can be spaces at the beginning or at the end of the cstring argument
		//2. A word can be separated from another word by one or more spaces
		//3. There is no any tab in the cstring
		//4. There is no any punctuation mark in the cstring
	cout << endl << "Testing countWords function";
	cout << endl << "---------------------------" << endl;
	char s14[21];
	int r1 = rand() % 10;
	for (int i = 0; i < r1; i++)
		s14[i] = ' ';
	int r2 = 20 - rand() % 10;
	for (int i = r1; i < r2; i++)
		s14[i] = rand()%3 == 0 ? ' ' : rand() % 26 + 97;
	for (int i = r2; i < 20; i++)
		s14[i] = ' ';
	s14[20] = '\0';
	cout << "There are " << countWords(s14) << " words in \"" << s14 << "\"" << endl;

	//Delete dynamic arrays
	cout << endl << "Deleting heap memories";
	cout << endl << "----------------------" << endl;
	cout << "Deleting s2."; delete[] s2; cout << " Done!" << endl;
	cout << "Deleting s3."; delete[] s3; cout << " Done!" << endl;
	cout << "Deleting s5."; delete[] s5; cout << " Done!" << endl;
	cout << "Deleting s6."; delete[] s6; cout << " Done!" << endl;
	cout << "Deleting s7."; delete[] s7; cout << " Done!" << endl;
	cout << "Deleting s8."; delete[] s8; cout << " Done!" << endl;
	cout << "Deleting s11."; delete[] s11; cout << " Done!" << endl;
	cout << endl;

	system("Pause");
	return 0;
}

2, Topic analysis

The title above clearly requires us not to use the string Library of C + + and not to include cstdlib and math. Without changing the main function, we need to realize the output in the picture. The meaning is already very clear, that is, we need to realize some string operations ourselves. The operation of cstring tests the author's ability to understand and use the pointer. Record it here so that you can review it from time to time in the future.

3, Function implementation

For the convenience of students, we first typedef the char pointer type as the charPointer type, and then we all use charPointer instead of char*

3.1 string length calculation

Behave yourself.
The code is as follows:

int cstrlen(charPointer pointer)
{
	int i = 0;
	while (pointer[i] != '\0') i++;
	return i;
}

(end of string '\ 0' is not evaluated.)

3.2 count the number of occurrences of a letter

The same rules
The code is as follows:

int countChars(charPointer pointer, char cha)
{
	int i = 0,count=0;
	while (pointer[i] != '\0')
	{
		if (pointer[i] == cha)
			count++;
		i++;
	}
	return count;
}

3.3 count the number of letters in a specific interval

The title requires that the right boundary can be the default value, and the default value is the string length.
The code is as follows:

bool isFound(charPointer pointer,char cha,int a,int b=0)
{
	if (b == 0)
		b = cstrlen(&cha);
	for (int i = a; i <= b; i++)
	{
		if (pointer[i] == cha)
			return true;
	}
	return false;
}

3.4 string copying

The first point is that when we first enter the function, we will delete the pointer of the destination string indiscriminately, and then re apply for a memory one byte larger than the length of the source string (using the first function we wrote). Because we need to add another '\ 0' at the end, otherwise the heap will crash during subsequent delete operations.
The code is as follows:

void cstringCopy(charPointer& destination, const charPointer& source)
{	
	delete[]destination;
	int i=0;
	destination = new char[cstrlen(source)+1];
	for (i = 0; i < cstrlen(source); i++)
	{
		destination[i] = source[i];
	}
	destination[i] = '\0';
}

3.5 character rotation

When the given parameter r > 0, rotate left and R < 0, rotate right. There is no requirement for time here. We use the circular rotation method
The code is as follows:

void rotateString(charPointer pointer, int r)
{
	int len = cstrlen(pointer);
	if (len!=0)
	r %= len;
	if (r >= 0)
	{
		while (r--)
		{
			char temp = pointer[0];
			for (int i = 0; i<len-1; i++)
				pointer[i] = pointer[i + 1];
			pointer[len-1] = temp;
		}
	}
	else
	{
		while (r++)
		{
			char temp = pointer[len-1];
			for (int i = len-1; i > 0; i--)
				pointer[i] = pointer[i - 1];
			pointer[0] = temp;
		}
	}
}

3.6 adding letters after strings

Each string is of just the right size. There is no space for new letters. At this time, we can't simply change the '\ 0' position to the corresponding character after the string, but we need to re apply for space, otherwise there will be problems in subsequent delete.
The code is as follows:

void append(charPointer &pointer, char cha)
{
	int r = cstrlen(pointer), i = 0;
	charPointer temp = new char[r + 2];
	for (i = 0; i < r; i++)
		temp[i] = pointer[i];
	temp[r] = cha;
	temp[r + 1] = '\0';
	cstringCopy(pointer, temp);
}

Note that there are two extra bytes in new, one for adding letters and the other for storing '\ 0'.

3.7 append string after string

It is an upgraded version of 3.6. There is no more nonsense. It is overloaded directly.
The code is as follows:

void append(charPointer &pointer, charPointer str)
{
	int r1 = cstrlen(pointer),r2=cstrlen(str),i=0,j=0;
	charPointer temp = new char[r1 + r2 + 2];
	for (i = 0; i < r1; i++)
		temp[i] = pointer[i];
	for (; i < r1 + r2; i++, j++)
		temp[i] = str[j];
	temp[r1 + r2] = '\0';
	cstringCopy(pointer, temp);
}

3.8 delete the first target letter in the string

The code is as follows:

bool removeChar(charPointer pointer,char cha)
{
	int r = cstrlen(pointer);
	for (int i = 0; i < r; i++)
	{
		if (pointer[i] == cha)
		{
			for (int j = i; j < r-1; j++)
			{
				pointer[j] = pointer[j + 1];
			}
			pointer[r - 1]='\0';
			return true;
		}
	}
	return false;
}

3.9 delete all target letters in the string

3.8 plus, direct loop implementation.
The code is as follows:

void removeCharAll(charPointer pointer, char cha)
{
	while (removeChar(pointer, cha));
}

3.10 judge whether two strings are equal

Judge the length first, and then judge word by word.
The code is as follows:

bool isEqual(charPointer pointer1, charPointer pointer2)
{
	int r1 = cstrlen(pointer1), r2 = cstrlen(pointer2);
	if (r1 != r2)
		return false;
	else
	{
		for (int i = 0;i < r1;i++)
		{
			if (pointer1[i] != pointer2[i])
				return false;
		}
	}
	return true;
}

3.11 judge whether two strings are isomorphic

There are only lowercase English letters in the title. We use 26 characters to count.
The code is as follows:

bool isAnagram(charPointer pointer1, charPointer pointer2)
{
	int a[26] = { 0 }, b[26] = { 0 };
	if (cstrlen(pointer1) != cstrlen(pointer2))
		return false;
	else
	{
		for (int i = 0; i < cstrlen(pointer1); i++)
		{
			a[pointer1[i] - 97]++;
			b[pointer2[i] - 97]++;
		}
		for (int i = 0; i < 26; i++)
		{
			if (a[i] != b[i])
				return false;
		}
	}
	return true;
}

3.12 cross combination of two strings (zigzag combination)

Apply for a large enough memory, then divide it into two categories according to the length of two characters, and then take the contents of two characters with parity.
The code is as follows:

charPointer zigzagMerge(charPointer pointer1,charPointer pointer2)
{
	charPointer temp=new char[100];
	if (cstrlen(pointer1)>cstrlen(pointer2))
	{
		for (int i = 0; i < 2 * cstrlen(pointer2); i++)
		{
			if (i % 2 == 0)
			{
				temp[i] = pointer1[i / 2];
			}
			else
			{
				temp[i] = pointer2[i / 2];
			}
		}
		for (int i = cstrlen(pointer1) - cstrlen(pointer2) - 1, j = 2 * cstrlen(pointer2)-1; i < cstrlen(pointer1); i++, j++)
		{
			temp[j] = pointer1[i];
		}
	}
	else
	{
		for (int i = 0; i < 2 * cstrlen(pointer1); i++)
		{
			if (i % 2 == 0)
			{
				temp[i] = pointer1[i / 2];
			}
			else
			{
				temp[i] = pointer2[i / 2];
			}
		}
		for (int i = cstrlen(pointer1) - cstrlen(pointer2) - 1, j = 2 * cstrlen(pointer2) - 1; i < cstrlen(pointer1); i++, j++)
		{
			temp[j] = pointer2[i];
		}
	}
	temp[cstrlen(pointer1) + cstrlen(pointer2)-1]='\0';
	return temp;
}

3.13 character string of character string

Given the starting position and the length of the substring, if it exceeds the length, it will be taken until the last character in the string.
The code is as follows:

charPointer getSubString(charPointer pointer, int startIndex, int length)
{
	charPointer temp = new char[100];
	int j=0;
	for (int i = startIndex; (i < startIndex + length) && pointer[i] != '\0'; i++,j++)
	{
		temp[j] = pointer[i];
	}
	temp[j] = '\0';
	return temp;
}

3.14 judge whether the given string is a substring of the target string

First compare the length and call the function of 3.13
The code is as follows:

bool isSubString(charPointer pointer1, charPointer pointer2)
{
	int r1 = cstrlen(pointer1), r2 = cstrlen(pointer2);
	if (r1>r2 )
		return false;
	else
	{
		for (int i = 0; i < r2 - r1; i++)
		{
			charPointer temp = getSubString(pointer2, i, r1);
			if (isEqual(temp, pointer1))
				return true;
		}
	}
	return false;
}

3.15 how many word s are there in the judgment string

The code is as follows:

int countWords(charPointer pointer)
{
	int i = 0, num = 0;
	char c1, c2 = ' ';
	while (pointer[i] != '\0')
	{
		c1 = pointer[i];
		if (i == 0)	
		{
			c2 = ' ';
		}
		else	
		{
			c2 = pointer[i - 1];
		}
		if (c1 != ' '&&c2 == ' ')	
		{
			num++;
		}
		i++;
	}
	return num;
}

4, Overall code

All codes are written in vs2013. Please pay attention to version compatibility.

// ConsoleApplication1.cpp: defines the entry point for the console application.
//

#include "stdafx.h"
#include <iostream>
#include <ctime>

using namespace std;

//Define a type def that will be very useful when we implement our functions.
typedef char* charPointer;
//This type def will make cstring parameter passing by reference easy to debug
//Example void foo(charPointer& x) is easier to debug than void foo(char* & x)

int cstrlen(charPointer pointer)
{
	int i = 0;
	while (pointer[i] != '\0') i++;
	return i;
}

int countChars(charPointer pointer, char cha)
{
	int i = 0,count=0;
	while (pointer[i] != '\0')
	{
		if (pointer[i] == cha)
			count++;
		i++;
	}
	return count;
}

bool isFound(charPointer pointer,char cha,int a,int b=0)
{
	if (b == 0)
		b = cstrlen(&cha);
	for (int i = a; i <= b; i++)
	{
		if (pointer[i] == cha)
			return true;
	}
	return false;
}

void cstringCopy(charPointer& destination, const charPointer& source)
{	
	delete[]destination;
	int i=0;
	destination = new char[cstrlen(source)+1];
	for (i = 0; i < cstrlen(source); i++)
	{
		destination[i] = source[i];
	}
	destination[i] = '\0';
}

void rotateString(charPointer pointer, int r)
{
	int len = cstrlen(pointer);
	if (len!=0)
	r %= len;
	if (r >= 0)
	{
		while (r--)
		{
			char temp = pointer[0];
			for (int i = 0; i<len-1; i++)
				pointer[i] = pointer[i + 1];
			pointer[len-1] = temp;
		}
	}
	else
	{
		while (r++)
		{
			char temp = pointer[len-1];
			for (int i = len-1; i > 0; i--)
				pointer[i] = pointer[i - 1];
			pointer[0] = temp;
		}
	}
}

void append(charPointer &pointer, char cha)
{
	int r = cstrlen(pointer), i = 0;
	charPointer temp = new char[r + 2];
	for (i = 0; i < r; i++)
		temp[i] = pointer[i];
	temp[r] = cha;
	temp[r + 1] = '\0';
	cstringCopy(pointer, temp);
}

void append(charPointer &pointer, charPointer str)
{
	int r1 = cstrlen(pointer),r2=cstrlen(str),i=0,j=0;
	charPointer temp = new char[r1 + r2 + 2];
	for (i = 0; i < r1; i++)
		temp[i] = pointer[i];
	for (; i < r1 + r2; i++, j++)
		temp[i] = str[j];
	temp[r1 + r2] = '\0';
	cstringCopy(pointer, temp);
}

bool removeChar(charPointer pointer,char cha)
{
	int r = cstrlen(pointer);
	for (int i = 0; i < r; i++)
	{
		if (pointer[i] == cha)
		{
			for (int j = i; j < r-1; j++)
			{
				pointer[j] = pointer[j + 1];
			}
			pointer[r - 1]='\0';
			return true;
		}
	}
	return false;
}

void removeCharAll(charPointer pointer, char cha)
{
	while (removeChar(pointer, cha));
}

bool isEqual(charPointer pointer1, charPointer pointer2)
{
	int r1 = cstrlen(pointer1), r2 = cstrlen(pointer2);
	if (r1 != r2)
		return false;
	else
	{
		for (int i = 0;i < r1;i++)
		{
			if (pointer1[i] != pointer2[i])
				return false;
		}
	}
	return true;
}

bool isAnagram(charPointer pointer1, charPointer pointer2)
{
	int a[26] = { 0 }, b[26] = { 0 };
	if (cstrlen(pointer1) != cstrlen(pointer2))
		return false;
	else
	{
		for (int i = 0; i < cstrlen(pointer1); i++)
		{
			a[pointer1[i] - 97]++;
			b[pointer2[i] - 97]++;
		}
		for (int i = 0; i < 26; i++)
		{
			if (a[i] != b[i])
				return false;
		}
	}
	return true;
}

charPointer zigzagMerge(charPointer pointer1,charPointer pointer2)
{
	charPointer temp=new char[100];
	if (cstrlen(pointer1)>cstrlen(pointer2))
	{
		for (int i = 0; i < 2 * cstrlen(pointer2); i++)
		{
			if (i % 2 == 0)
			{
				temp[i] = pointer1[i / 2];
			}
			else
			{
				temp[i] = pointer2[i / 2];
			}
		}
		for (int i = cstrlen(pointer1) - cstrlen(pointer2) - 1, j = 2 * cstrlen(pointer2)-1; i < cstrlen(pointer1); i++, j++)
		{
			temp[j] = pointer1[i];
		}
	}
	else
	{
		for (int i = 0; i < 2 * cstrlen(pointer1); i++)
		{
			if (i % 2 == 0)
			{
				temp[i] = pointer1[i / 2];
			}
			else
			{
				temp[i] = pointer2[i / 2];
			}
		}
		for (int i = cstrlen(pointer1) - cstrlen(pointer2) - 1, j = 2 * cstrlen(pointer2) - 1; i < cstrlen(pointer1); i++, j++)
		{
			temp[j] = pointer2[i];
		}
	}
	temp[cstrlen(pointer1) + cstrlen(pointer2)-1]='\0';
	return temp;
}

charPointer getSubString(charPointer pointer, int startIndex, int length)
{
	charPointer temp = new char[100];
	int j=0;
	for (int i = startIndex; (i < startIndex + length) && pointer[i] != '\0'; i++,j++)
	{
		temp[j] = pointer[i];
	}
	temp[j] = '\0';
	return temp;
}

bool isSubString(charPointer pointer1, charPointer pointer2)
{
	int r1 = cstrlen(pointer1), r2 = cstrlen(pointer2);
	if (r1>r2 )
		return false;
	else
	{
		for (int i = 0; i < r2 - r1; i++)
		{
			charPointer temp = getSubString(pointer2, i, r1);
			if (isEqual(temp, pointer1))
				return true;
		}
	}
	return false;
}

int countWords(charPointer pointer)
{
	int i = 0, num = 0;
	char c1, c2 = ' ';
	while (pointer[i] != '\0')
	{
		c1 = pointer[i];
		if (i == 0)	
		{
			c2 = ' ';
		}
		else	
		{
			c2 = pointer[i - 1];
		}
		if (c1 != ' '&&c2 == ' ')	
		{
			num++;
		}
		i++;
	}
	return num;
}
int main()
{
	/*
	This program is designed to test the functions you need to implement.
	You should NOT remove any line of code from this test program.
	But you may add more test code in the program if you like.
	*/
	cout << "This program is designed to help you test your functions." << endl;
	srand(time(0));

	//Test cstrlen function
	//The function must return the number of printable characters of a cstring argument
	cout << endl << "Testing cstrlen function";
	cout << endl << "------------------------" << endl;
	char s1[] = "irregular";
	cout << "The length of \"" << s1 << "\" is " << cstrlen(s1) << endl;
	cout << "The length of \"\" is " << cstrlen("") << endl;

	//Test countChars function
	//The function must return the number of times a character argument is found in a cstring argument
	cout << endl << "Testing countChars function";
	cout << endl << "---------------------------" << endl;
	char ch = rand() % 26 + 97;
	int count = countChars(s1, ch);
	cout << "'" << ch << "' is found in \"" << s1 << "\" " << count << " times." << endl;
	
	//Test isFound function
	//The function must return true if a character argument is found in a cstring argument in the index interval [a, b)
	//The integer arguments a and b are optional arguments. If they are not suplied, then the function uses
	//the values a = 0 and b = the length of the cstring argument
	//The function must return false if the character argument is not found in the cstring argument in the interval [a, b)
	cout << endl << "Testing isFound function";
	cout << endl << "-------------------------" << endl;
	int a = 2, b = cstrlen(s1);
	ch = rand() % 26 + 97;
	bool flag = isFound(s1, ch, a, b);
	if (flag)
		cout << "'" << ch << "' is found in \"" << s1 << "\" in the index interval [" << a << ", " << b << ") " << endl;
	else
		cout << "'" << ch << "' is not found in \"" << s1 << "\" in the index interval [" << a << ", " << b << ") " << endl;

	a = 3;
	ch = rand() % 26 + 97;
	flag = isFound(s1, ch, a);
	if (flag)
		cout << "'" << ch << "' is found in \"" << s1 << "\" in the index interval [" << a << ", " << b << ") " << endl;
	else
		cout << "'" << ch << "' is not found in \"" << s1 << "\" in the index interval [" << a << ", " << b << ") " << endl;

	b = 8;
	ch = rand() % 26 + 97;
	flag = isFound(s1, ch, a, b);
	if (flag)
		cout << "'" << ch << "' is found in \"" << s1 << "\" in the index interval [" << a << ", " << b << ") " << endl;
	else
		cout << "'" << ch << "' is not found in \"" << s1 << "\" in the index interval [" << a << ", " << b << ") " << endl;

	//Test cstringCopy function
	//Function signature: cstringCopy(destination, source)
	//The function must copy the source cstring to the destination cstring
	//The function must first delete the memory allocated for destination cstring and then
	//allocate enough memory to perform the copying without any index out of bounds error
	//Remark: You need to pass the destination cstring argument by reference. Thus the function
	//signature should be something like: void cstringCopy(charPointer& destination, const charPointer& source)
	
	cout << endl << "Testing cstringCopy function";
	cout << endl << "------------------------" << endl;
	char* s2 = new char('\0');
	cstringCopy(s2, "irregular");
	cout << "A copy of \"irregular\" is \"" << s2 << "\"" << endl;

	char* s3 = new char('\0');
	cstringCopy(s3, s2);
	cout << "A copy of \"" << s2 << "\" is \"" << s3 << "\"" << endl;

	delete[] s2;
	s2 = new char('\0');
	cout << "s2 is modified to \"" << s2 << "\" but s3 is still \"" << s3 << "\"" << endl;

	delete[] s3;
	s3 = new char('\0');
	cstringCopy(s3, s2);
	cout << "A copy of \"" << s2 << "\" is \"" << s3 << "\"" << endl;
	
	//Test rotateString function
	//The function must rotate the characters of of its cstring argument by r units
	//If r > 0, rotate the characters of the argument to the left
	//If r < 0, rotate the characters of the argument to the right
	//Please note the value of r can be any integer including larger than the length of s
	//For example,
	//"asmara" rotated to the left by 0 becomes "asmara"
	//"asmara" rotated to the left by 1 becomes "smaraa"
	//"asmara" rotated to the left by 2 becomes "maraas"
	//similarly
	//"asmara" rotated to the right by 0 becomes "asmara"
	//"asmara" rotated to the right by 1 becomes "aasmar"
	//"asmara" rotated to the right by 2 becomes "raasma"

	cout << endl << "Testing rotateString function";
	cout << endl << "-----------------------------" << endl;
	char s4[] = "asmara";
	for (int i = 0; i < 10; i++)
	{
		int r = rand() % 101 - 50;
		if (r > 0)
			cout << "\"" << s4 << "\" rotated " << r << " times to the left becomes ";
		else
			cout << "\"" << s4 << "\" rotated " << -r << " times to the right becomes ";
		rotateString(s4, r);
		cout << "\"" << s4 << "\"" << endl;
	}
	
	//Test append character function
	//The function must concatenate the character argument to the cstring argument.
	//Hint: Parameter passing by reference is needed
	cout << endl << "Testing append character function";
	cout << endl << "---------------------------------" << endl;
	char* s5 = new char('\0');
	for (int i = 0; i < 20; i++)
	{
		ch = rand() % 26 + 97;
		cout << "Appending '" << ch << "' to \"" << s5 << "\" gives \"";
		append(s5, ch);
		cout << s5 << "\"" << endl;
	}

	//Test append cstring function
	//Function signature: append(destination, source)
	//The function must append all the characters of source cstring to the destination cstring
	//The function must not modify the source cstring
	//Hint: Make use of your append character function when you implement this function
	//Hint: Parameter passing by reference is needed
	cout << endl << "Testing append cstring function";
	cout << endl << "-------------------------------" << endl;
	char* s6 = new char('\0');
	cout << "Appending \"" << s5 << "\" to \"" << s6 << "\" gives \"";
	append(s6, s5);
	cout << s6 << "\"" << endl;

	//Test removeChar function
	//The function must remove the first character of the cstring argument that is equal to the character argument
	//Then the function must return true if it has found a character and removed it; otherwise returns false
	//Hint: Parameter passing by reference is needed
	cout << endl << "Testing removeChar function";
	cout << endl << "---------------------------" << endl;
	char* s7 = new char[11];
	for (int i = 0; i < 10; i++)
		s7[i] = rand() % 26 + 97;
	s7[10] = '\0';
	for (int i = 0; i < 20; i++)
	{
		ch = rand() % 26 + 97;
		cout << "Removing '" << ch << "' from \"" << s7 << "\" gives \"";
		removeChar(s7, ch);
		cout << s7 << "\"" << endl;
	}

	//Test removeCharAll function
	//The function must remove all characters of the cstring argument that are equal to the character argument
	//Hint: Use your removeChar function when you implement this function
	cout << endl << "Testing removeCharAll function";
	cout << endl << "------------------------------" << endl;
	char* s8 = new char[11];
	for (int i = 0; i < 10; i++)
		s8[i] = rand() % 3 + 97;
	s8[10] = '\0';
	ch = rand() % 3 + 97;
	cout << "Removing all occurences of '" << ch << "' from \"" << s8 << "\" gives \"";
	removeCharAll(s8, ch);
	cout << s8 << "\"" << endl;
	
	//Test isEqual function
	//The function must return true if the two cstring arguments have equal length and their characters at
	//the same indexes are equal. Otherwise return false.
	cout << endl << "Testing isEqual function";
	cout << endl << "------------------------" << endl;
	char s9[] = "yonas";
	char s10[] = "yonas";
	if (isEqual(s9, s10))
		cout << "\"" << s9 << "\" and \"" << s10 << "\" are equal" << endl;
	else
		cout << "\"" << s9 << "\" and \"" << s10 << "\" are not equal" << endl;
	if (isEqual("CMPT130", "CMPT135"))
		cout << "CMPT130 and CMPT135 are equal" << endl;
	else
		cout << "CMPT130 and CMPT135 are not equal" << endl;
	
	//Test isAnagram function
	//The function must return true if the two cstring arguments are anagrams of each other.
	//Otherwise return false
	//Definition: Two cstrings are anagrams of each other if every character of one cstring is found
	//in the other cstring and that the number of times the character appears in both cstrings are equal
	cout << endl << "Testing isAnagram function";
	cout << endl << "--------------------------" << endl;
	if (isAnagram("massachussettes", "tessetsuchmassa") == true)
		cout << "massachussettes and tessetsuchmassa are anagrams" << endl;
	else
		cout << "massachussettes and tessetsuchmassa are not anagrams" << endl;
	if (isAnagram("CMPT130", "CMPT135") == true)
		cout << "CMPT130 and CMPT135 are anagrams" << endl;
	else
		cout << "CMPT130 and CMPT135 are not anagrams" << endl;
	
	//Test zigzagMerge function
	//Function signature: zigzagMerge(cstring1, cstring2)
	//The function must return a new cstring by merging (combining) the characters of cstring1 and cstring2 in zigzag form.
	//That is
	//The first character of the new cstring is the first character of cstring1
	//The second character of the new cstring is the first character of cstring2
	//The third character of the new cstring is the second character of cstring1
	//The fourth character of the new cstring is the second character of cstring2
	//The fifth character of the new cstring is the third character of cstring1
	//The sixth character of the new cstring is the third character of cstring2
	//etc
	//When either cstring1 or cstring2 reaches to its end, the remaining characters of the other are
	//appended to the new cstring
	//For example, the zigzagMerge of "abc" and "12345" will be "a1b2c345"
	cout << endl << "Testing zigzagMerge function";
	cout << endl << "----------------------------" << endl;
	char* s11 = zigzagMerge("cmpt130", "123");
	cout << "The zigzag merge of \"cmpt130\" and \"123\" is \"" << s11 << "\"" << endl;
	
	//Test getSubString function
	//Function signature: getSubString(cstring, startIndex, length)
	//The function must return a new cstring made from the characters of the cstring argument starting from
	//the startIndex argument and containing as many as the length argument characters.
	//If the cstring argument has fewer characters starting from the startIndex upto its last character,
	//then this function must return a substring consisting of only the available characters starting from
	//the startIndex upto its last character. In this case, the returned substring will have less than length characters.
	cout << endl << "Testing getSubString function";
	cout << endl << "-----------------------------" << endl;
	char s12[] = "irresponsible";
	for (int i = 0; i < 5; i++)
	{
		int index = rand() % cstrlen(s1);
		int len = rand() % cstrlen(s1) + 1;
		char* s13 = getSubString(s12, index, len);
		cout << "A substring of \"" << s12 << "\" starting from index " << index << " with " << len << " characters is ";
		cout << "\"" << s13 << "\"" << endl;
		delete[] s13;
	}

	//Test isSubString function
	//Function signature: isSubString(cstring1, cstring2)
	//This function must return true if cstring1 argument is a substring of cstring2 argument.
	//Otherwise returns false.
	//Definition: cstring1 is a substring of cstring2 if there exist valid integers startIndex and length such that
	//the function call getSubString(cstring2, startIndex, length) returns a cstring that is equal to cstring1.
	cout << endl << "Testing isSubString function";
	cout << endl << "----------------------------" << endl;
	if (isSubString("set", "massachussettes"))
		cout << "\"set\" is a substring of \"massachussettes\"" << endl;
	else
		cout << "\"set\" is not a substring of \"massachussettes\"" << endl;

	if (isSubString("", "c"))
		cout << "\"\" is a substring of \"c\"" << endl;
	else
		cout << "\"\" is not a substring of \"c\"" << endl;

	if (isSubString("test", "massachussettes"))
		cout << "\"test\" is a substring of \"massachussettes\"" << endl;
	else
		cout << "\"test\" is not a substring of \"massachussettes\"" << endl;

	//Test countWords function
	//This function must return the number of words contained in a cstring argument.
	//Here, a word means some characters with no any spaces in between.
	//Example: If the cstring argument is "What    a     nice           problem "
	//Then you see that there are FOUR words in this cstring, namely
	//     1. What      2. a       3. nice      4. problem
	//Thus your function then must return 4

	//Please note that,
	//1. There can be spaces at the beginning or at the end of the cstring argument
	//2. A word can be separated from another word by one or more spaces
	//3. There is no any tab in the cstring
	//4. There is no any punctuation mark in the cstring
	cout << endl << "Testing countWords function";
	cout << endl << "---------------------------" << endl;
	char s14[21];
	int r1 = rand() % 10;
	for (int i = 0; i < r1; i++)
		s14[i] = ' ';
	int r2 = 20 - rand() % 10;
	for (int i = r1; i < r2; i++)
		s14[i] = rand() % 3 == 0 ? ' ' : rand() % 26 + 97;
	for (int i = r2; i < 20; i++)
		s14[i] = ' ';
	s14[20] = '\0';
	cout << "There are " << countWords(s14) << " words in \"" << s14 << "\"" << endl;
	
	//Delete dynamic arrays
	cout << endl << "Deleting heap memories";
	cout << endl << "----------------------" << endl;
	cout << "Deleting s2."; delete[] s2; cout << " Done!" << endl;
	cout << "Deleting s3."; delete[] s3; cout << " Done!" << endl;
	cout << "Deleting s5."; delete[] s5; cout << " Done!" << endl;
	cout << "Deleting s6."; delete[] s6; cout << " Done!" << endl;
	cout << "Deleting s7."; delete[] s7; cout << " Done!" << endl;
	cout << "Deleting s8."; delete[] s8; cout << " Done!" << endl;
	cout << "Deleting s11."; delete[] s11; cout << " Done!" << endl;
	cout << endl;
	
	system("Pause");
	return 0;
}

Topics: C++ pointer string Functional Programming