Chapter 1 | Arrays and Strings
1.1 Implement an algorithm to determine if a string has all unique characters What if you can not use additional data structures?
#include <stdio.h>
#include <string>
#include <iostream>
#include <time.h>
#include <math.h>
using namespace std;
bool isUniqString(string s)
{
bool hit[256] = {0};
for (int i = 0; i < s.size(); i++)
{
int val = s[i];
if (hit[val])
{
return false;
}
hit[val] = true;
}
return true;
}
bool isUniqString2(string s)
{
long hit = 0;
for (int i = 0; i < s.size(); i++)
{
int val = s[i] - 'a';
if ((hit & (1 << val)) > 0)
{
return false;
}
hit |= (1 << val);
}
return true;
}
int main(void)
{
clock_t start;
clock_t end;
float duration;
start = clock();
string words[2] = {"adck", "aabb"};
for (int i = 0; i < 2; i++)
{
printf("function 1%s : %d \n", words[i].c_str(), isUniqString(words[i]));
printf("function 2%s : %d \n", words[i].c_str(), isUniqString2(words[i]));
}
end = clock() - start;
printf("It took me %d clocks %f seconds \n", end, ((float)end)/CLOCKS_PER_SEC);
}
1.2 Write code to reverse a C-Style String (C-String means that “abcd” is represented as five characters, including the null character )
#include <iostream>
#include <string>
#include <stdio.h>
#include <time.h>
#include <math.h>
#include <algorithm>
//c++ sting reverse
void stl_reverse(std::string& str)
{
reverse(str.begin(), str.end());
}
void bad_reverse(std::string& str)
{
std::string tmp(str);
std::string::size_type ix = str.size() - 1;
for (std::string::size_type i = 0; i < str.size(); i++)
{
str[i] = tmp[ix--];
}
}
void good_reverse(std::string& str)
{
size_t first;
size_t last;
first = 0;
last = str.length() -1;
while (first < last)
{
std::swap(str[first++], str[last--]);
}
}
void reverse(std::string& str)
{
char tmp;
size_t first;
size_t last;
first = 0;
last = str.length() - 1;
while (first < last)
{
tmp = str[first];
str[first] = str[last];
str[last] = tmp;
first++;
last--;
}
}
//c char* reverse
void bad_reverse(char* str)
{
char* tmp = new char[strlen(str)];
strcpy(tmp, str);
size_t ix = strlen(str) - 1;
for (size_t i = 0; i < strlen(str); i++)
{
str[i] = tmp[ix--];
}
delete[] tmp;
}
void good_reverse(char* str)
{
char tmp;
size_t start;
size_t end;
start = 0;
end = strlen(str) - 1;
while (start < end)
{
tmp = str[start];
str[start] = str[end];
str[end] = tmp;
start++;
end--;
}
}
int main(void)
{
using namespace std;
clock_t start, end;
std::string str = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
start = clock();
for (int i = 0 ; i != 10000001 ; i++)
{
bad_reverse(str);
}
end = clock() - start;
cout << str << endl;
printf("bad reverse took me %d ticks %f seconds \n", end, ((float)end)/CLOCKS_PER_SEC);
start = clock();
for (int i = 0 ; i != 10000001 ; i++)
{
stl_reverse(str);
}
end = clock() - start;
cout << str << endl;
printf("stl reverse took me %d ticks %f seconds \n", end, ((float)end)/CLOCKS_PER_SEC);
start = clock();
for (int i = 0 ; i != 10000001 ; i++)
{
good_reverse(str);
}
end = clock() - start;
cout << str << endl;
printf("good reverse took me %d ticks %f seconds \n", end, ((float)end)/CLOCKS_PER_SEC);
start = clock();
for (int i = 0 ; i != 10000001 ; i++)
{
reverse(str);
}
end = clock() - start;
cout << str << endl;
printf("reverse took me %d ticks %f seconds \n", end, ((float)end)/CLOCKS_PER_SEC);
char cs[] = "0123456789abcdefghijklmnopqrstuvwxyz";
start = clock();
for (int i = 0 ; i != 10000001 ; i++)
{
bad_reverse(cs);
}
end = clock() - start;
cout << cs << endl;
printf("reverse took me %d ticks %f seconds \n", end, ((float)end)/CLOCKS_PER_SEC);
start = clock();
for (int i = 0 ; i != 10000001 ; i++)
{
good_reverse(cs);
}
end = clock() - start;
cout << cs << endl;
printf("reverse took me %d ticks %f seconds \n", end, ((float)end)/CLOCKS_PER_SEC);
}
1.3 Design an algorithm and write code to remove the duplicate characters in a string without using any additional buffer NOTE: One or two additional variables are fine An extra copy of the array is not.FOLLOW UP Write the test cases for this method
#include <iostream>
#include <string>
#include <time.h>
#include <algorithm>
#include <math.h>
//use char[] description the char of str
std::string removeDuplicate(std::string str)
{
int size;
int loop;
int pointer;
size = str.length();
if(size < 2)
{
return "";
}
char hit[256] = {0};
loop = 0;
pointer = 0;
while (pointer < size)
{
int val = str[pointer];
if (hit[val] != '\0')
{
pointer++;
continue;
}
hit[val] = '1';
str[loop] = str[pointer];
loop++;
pointer++;
}
return std::string(str.c_str(), loop);
}
//use long bit description the char of str
std::string removeDuplicate2(std::string str)
{
int size;
long hit;
int loop;
int pointer;
size = str.length();
if(size < 2)
{
return "";
}
hit = 0;
loop = 0;
pointer = 0;
while (pointer < size)
{
long val = str[pointer];
if ((hit & (1<< val)) > 0)
{
pointer++;
continue;
}
hit |= 1 << val;
str[loop] = str[pointer];
loop++;
pointer++;
}
return std::string(str.c_str(), loop);
}
int main()
{
std::string str = "fdffdfdfdfdfdfdfdfd909";
std::string rt1 = removeDuplicate(str);
std::cout<<"rt1 is: "<<rt1<<std::endl;
std::string rt2 = removeDuplicate2(str);
std::cout<<"rt2 is: "<<rt2<<std::endl;
}
Test Cases:
1 String does not contain any duplicates, e g : abcd
2 String contains all duplicates, e g : aaaa
3 Null string
4 String with all continuous duplicates, e g : aaabbb
5 String with non-contiguous duplicate, e g : abababa
1.4 Write a method to decide if two strings are anagrams or not
1.4 Write a method to decide if two strings are anagrams or not
#include <iostream>
#include <string>
#include <time.h>
#include <algorithm>
#include <math.h>
#include <vector>
bool anagram(std::string s, std::string d)
{
int s_size = s.size();
int d_size = d.size();
if (s_size != d_size)
{
return false;
}
int count[256] = {0};
int num_uniq_chars = 0;
int num_complete_chars = 0;
for (int i = 0; i < s_size; i++)
{
int val = s[i];
if(0 == count[val])
{
num_uniq_chars++;
}
count[val]++;
}
for (int i = 0; i < d_size; i++)
{
int val = d[i];
if(0 == count[val])
{
return false;
}
count[val]--;
if (0 == count[val])
{
num_complete_chars++;
}
}
if (num_complete_chars == num_uniq_chars)
{
return true;
}
return false;
}
int main()
{
using namespace std;
vector<pair<string, string> > pairs;
pairs.push_back(std::make_pair("apple", "papel"));
pairs.push_back(std::make_pair("carrot", "tarroc"));
pairs.push_back(std::make_pair("hello", "llloh"));
string strs[3][2] = {{"apple", "papel"}, {"carrot", "tarroc"}, {"hello", "llloh"}};
for (int i = 0; i < sizeof(strs)/sizeof(strs[0]); i++)
{
bool ret = anagram(strs[i][0], strs[i][1]);
std::cout<<strs[i][0]<<" "<<strs[i][1]<<"rt is: "<<ret<<std::endl;
}
std::vector<pair<string, string> >::iterator pos;
for (pos = pairs.begin(); pos != pairs.end(); pos++)
{
bool ret = anagram(pos->first, pos->second);
std::cout<<pos->first<<" "<<pos->second<<"rt is: "<<ret<<std::endl;
}
}
1.6 Given an image represented by an NxN matrix, where each pixel in the image is 4 bytes, write a method to rotate the image by 90 degrees Can you do this in place?、
#include <iostream>
#include <stdio.h>
#include <math.h>
#include <algorithm>
#include <time.h>
#define MARTIX_SIZE 9
int rotate(int (*martix)[MARTIX_SIZE], int n)
{
if ( NULL == martix)
{
return -1;
}
for (int layer = 0; layer < n/2; layer++)
{
int first = layer;
int last = n - layer -1;
for (int i = first; i < last; i++)
{
int offset = i - first;
int restore = martix[first][i];
//left -> top
martix[first][i] = martix[last - offset][first];
//bottom -> left
martix[last - offset][first] = martix[last][last - offset];
//right -> bottom
martix[last][last - offset] = martix[i][last];
//top -> right
martix[i][last] = restore;
}
}
return 0;
}
int main()
{
int martix[MARTIX_SIZE][MARTIX_SIZE];
for (int i = 0; i < MARTIX_SIZE; i++)
{
for (int j = 0; j < MARTIX_SIZE; j++)
{
martix[i][j] = (i+1)*10 + j;
printf("%d ", martix[i][j]);
}
printf("\n");
}
rotate(martix, MARTIX_SIZE);
printf("After rotate! \n");
for (int i = 0; i < MARTIX_SIZE; i++)
{
for (int j = 0; j < MARTIX_SIZE; j++)
{
printf("%d ", martix[i][j]);
}
printf("\n");
}
return 0;
}
1.8 Given two strings, s1 and s2, write code to check if s2 is a rotation (i e , “waterbottle” is a rotation of “erbottlewat”)
#include <iostream>
#include <stdio.h>
#include <math.h>
#include <algorithm>
#include <time.h>
#include <string>
//c++ style
//identified s2 is a substring of s2 or ont
bool isSubStr(std::string s1, std::string s2)
{
size_t pos = s1.find(s2);
return pos != std::string::npos;
}
//identified s2 is a rotation of s1 or not
bool isRotation(std::string s1, std::string s2)
{
size_t length1 = s1.length();
size_t length2 = s2.length();
if (length1 != length2)
{
return false;
}
std::string combine = s2 + s2;
return isSubStr(combine, s1);
}
//c style
char* myStrstr(const char* s1, const char* s2)
{
if (NULL == s1 || s2 == NULL)
{
return NULL;
}
const char* t = s2;
const char* s = s1;
for (; '\0' != *s1; s1++)
{
for (t = s2, s = s1; '\0' != *t && *t == *s; s++, t++);
if ('\0' == *t)
{
return (char*)s1;
}
}
return NULL;
}
char* myStrcat(char* s, const char* append)
{
char* save = s;
for (; '\0' != *s; s++);
while ((*s++ = *append++) != '\0');
return save;
}
char* myStrcopy(char* dest, const char* source)
{
if (NULL == dest || NULL == source)
{
return NULL;
}
char* addr = dest;
while ((*dest++ = *source++) != '\0');
return addr;
}
//identified s2 is a substring of s1 or ont
bool c_isSubStr(const char* s1, const char* s2)
{
char* pointer = myStrstr(s1, s2);
return NULL != pointer;
}
//identified s2 is a rotation of s1 or not
bool c_isRotation(const char* s1, const char* s2)
{
size_t length1 = strlen(s1);
size_t length2 = strlen(s2);
if (length1 != length2)
{
return false;
}
char* combine = new char[strlen(s2)*2];
myStrcopy(combine, s2);
combine = myStrcat(combine, s2);
return c_isSubStr(combine, s1);
}
int main()
{
clock_t start;
clock_t end;
bool a = false;
bool b = false;
bool c = false;
std::string array[][2] = {{"apple", "ploap"}, {"waterbottle", "erbottlewat"}, {"camera", "macera"}};
start = clock();
for (int i = 0; i < 1000000; i++)
{
a = isRotation(array[0][0], array[0][1]);
b = isRotation(array[1][0], array[1][1]);
c = isRotation(array[2][0], array[2][1]);
}
end = clock() - start;
printf("%s, %s, %d \n", array[0][0].c_str(), array[0][1].c_str(), a);
printf("%s, %s, %d \n", array[1][0].c_str(), array[1][1].c_str(), b);
printf("c++ style: It took %d clocks %f seconds\n", end, ((float)end)/CLOCKS_PER_SEC);
start = clock();
for (int i = 0; i < 1000000; i++)
{
a = c_isRotation(array[0][0].c_str(), array[0][1].c_str());
b = c_isRotation(array[1][0].c_str(), array[1][1].c_str());
c = c_isRotation(array[2][0].c_str(), array[2][1].c_str());
}
end = clock() - start;
printf("%s, %s, %d \n", array[0][0].c_str(), array[0][1].c_str(), a);
printf("%s, %s, %d \n", array[1][0].c_str(), array[1][1].c_str(), b);
printf("c style: It took %d clocks %f seconds\n", end, ((float)end)/CLOCKS_PER_SEC);
return 0;
}
Chapter2
1.1
1.2