Popular Posts

Showing posts with label Strings. Show all posts
Showing posts with label Strings. Show all posts

Saturday, February 18, 2012

Length of the longest substring without repeating characters

Given a string, find the length of the longest substring without repeating characters. For example, the longest substrings without repeating characters for “ABDEFGABEF” are “BDEFGA” and “DEFGAB”, with length 6.
public class LongestSubString {

public static void main(String[] args) {
String str
= "ABDEFGABEF";

// Used for tracking the position of last occurrence of character in the
// string.
int[] chars = new int[256];
for (int i = 0; i < 256; i++) {
chars
[i] = -1;
}

int maxLength = 1;
int currentLength = 1;

for (int i = 0; i < str.length(); i++) {
int lastOccrrenceIndex = chars[str.charAt(i)];
if (lastOccrrenceIndex == -1
|| (i - currentLength > lastOccrrenceIndex)) {
currentLength
++;
} else {
if (currentLength > maxLength)
maxLength
= currentLength;
currentLength
= i - lastOccrrenceIndex;
}
chars
[str.charAt(i)] = i;
}
if (currentLength > maxLength)
maxLength
= currentLength;
System
.out.println(maxLength);
}
}


Time Complexity: O(n + d) where n is length of the input string and d is number of characters in input string alphabet. For example, if string consists of lowercase English characters then value of d is 26.
Auxiliary Space: O(d)

Refer : http://www.geeksforgeeks.org/archives/15859

Thursday, February 16, 2012

Second non repeating character

For a given a string, find its second non-repeating character.
public class SecondNonRepeatingCharacter {
/**
* Prints second non repeating character. O(N) time complexity O(1) space
* complexity
*
* @param args
*/
public static void main(String[] args) {
String str = "nonrepeatingcharacter";
// in the above string first non repeating character is o
// second one is p

// create an array to store char count
int[] charCount = new int[26];

// scan the string and store each character count.
for (int i = 0; i < str.length(); i++) {
charCount[str.charAt(i) - 'a']++;
}

int nonRepeatingCharcter = 0;
for (int i = 0; i < str.length(); i++) {
int index = str.charAt(i) - 'a';
if (charCount[index] == 1) {
nonRepeatingCharcter++;
if (nonRepeatingCharcter == 2) {
System.out.println("Secondnon repeating character : "
+ str.charAt(i));
break;
}
}
}

// prints how many times each character is repeated.duplicates are
// allowed
// for (int i = 0; i < str.length(); i++) {
// int index = str.charAt(i) - 'a';
// if (charCount[index] > 0)
// System.out.println("char : " + str.charAt(i) + " repeated : "
// + charCount[index] + " times.");
// }

}
}

Monday, February 13, 2012

Interleavings of two strings

Given two strings str1 and str2, write a function that prints all interleavings of the given two strings. You may assume that all characters in both strings are different

Example :
Input: str1 = "AB",  str2 = "CD"
Output:
    ABCD
    ACBD
    ACDB
    CABD
    CADB
    CDAB
public class InterLeavedStrings {
public static void main(String[] args) {
String str1 = "abc";
String str2 = "def";

if (str1 != null && str1.length() != 0 && str2 != null
&& str2.length() != 0) {
getInterLeavedStrings(str1, str2);
getInterLeavedStrings(str2, str1);
} else if (str1 == null || str1.length() == 0) {
System.out.println(str2);
} else {
System.out.println(str1);
}
}

private static void getInterLeavedStrings(String str1, String str2) {
int m = str1.length();
int n = str2.length();
for (int i = 1; i < m; i++) {
for (int j = 0; j < n; j++) {
System.out.println(str1.substring(0, i) + str2.substring(0, j)
+ str1.substring(i, m) + str2.substring(j, n));
}
}
}
}


Another variant of interleaving : Check a given string is interleaving of other two strings
 http://www.geeksforgeeks.org/archives/17750


Refer : http://www.geeksforgeeks.org/archives/17743

Tuesday, July 26, 2011

Are given characters of a string form palindrome?

Using the all characters of a given String how to specify either a palindrome or not.
Ex:-
1) String="teste"
After arrange all character we can made a palindrome String as "teset"
So output is TRUE.
2)String="hello"
we can not made a palindrome String
output is FALSE

Sort the given string and after call the below method
boolean isFormingPalindrome(String s) {
//Assume we are taking sorted string as an argument

if (s == null || s.length() == 0 || s.length() == 1)
return true;
int length = s.length();
// if it has even number of characters,it should have zero non repeated
// characters. else it should have one non repeated character
boolean isFirstNonRepeated = false;
if (length % 2 == 0) {
// for even length,there will not be any
// non repeated characters
isFirstNonRepeated = true;
}

char[] characters = s.toCharArray();
for (int i = 1; i < length; i = i + 2) {
if (characters[i - 1] != characters[i]) {
if (isFirstNonRepeated) {
return false;
} else {
i = i - 1;
isFirstNonRepeated = true;
}
}
}
return true;
}

Thursday, July 21, 2011

Reverse a line word by word AND swap two words in a given sentence

ex - my name is john
Then after reversing it will be like - john is name my


Method 1:
1. First scan the input string till midway and swap the first character with last and second character with second last and so on.
2. Second scan, swap the word within string the same way.


Problem II:
Swap two words in a given sentence
ex: my name is Khan in school.
swap name and in in the above sentence.
o/p : my in is name school.
Solution : 
Reverse the entire string  from starting word to ending word : Here starting word is name and ending word is in.So reverse the string from name to in using inplace string reversal algo.It requires O(n) traversal.
Step 1: 
Str = my name is Khan in school.
Str = my ni nahK si eman school
Step 2:
Now reverse the first word of the modifies string:
Str = my ni nahK si eman school
Str = my in nahk si eman school
Step 3 :
Now reverse the string after first word to second modified word.
Str = my in nahk si eman school
Str = my in is Khan eman school(after reversal)
Step 4 :
Now reverse the second word
Str = my in is Khan school
Str= my in is Khan name school

Original sentence         : my name is Khan in school.
After final modification : my in is Khan name school
Got the desired output.in and name are swapped in the given sentence.

Saturday, March 19, 2011

Levenshtein distance Or Edit Distance between Two Strings


   The words `computer' and `commuter' are very similar, and a change of just one letter, p->m will change the first word into the second. The word `sport' can be changed into `sort' by the deletion of the `p', or equivalently, `sort' can be changed into `sport' by the insertion of `p'.
    The edit distance of two strings, s1 and s2, is defined as the minimum number of point mutations required to change s1 into s2, where a point mutation is one of:
change a letter,
insert a letter or
delete a letter
The following recurrence relations define the edit distance, d(s1,s2), of two strings s1 and s2:
d('', '') = 0               -- '' = empty string
d(s, '')  = d('', s) = |s|  -- i.e. length of s
d(s1+ch1, s2+ch2)
  = min( d(s1, s2) + if ch1=ch2 then 0 else 1 fi,
         d(s1+ch1, s2) + 1,
         d(s1, s2+ch2) + 1 )
The first two rules above are obviously true, so it is only necessary consider the last one. Here, neither string is the empty string, so each has a last character, ch1 and ch2 respectively. Somehow, ch1 and ch2 have to be explained in an edit of s1+ch1 into s2+ch2. If ch1 equals ch2, they can be matched for no penalty, i.e. 0, and the overall edit distance is d(s1,s2). If ch1 differs from ch2, then ch1 could be changed into ch2, i.e. 1, giving an overall cost d(s1,s2)+1. Another possibility is to delete ch1 and edit s1 into s2+ch2, d(s1,s2+ch2)+1. The last possibility is to edit s1+ch1 into s2 and then insert ch2, d(s1+ch1,s2)+1. There are no other alternatives. We take the least expensive, i.e. min, of these alternatives.
The recurrence relations imply an obvious ternary-recursive routine. This is not a good idea because it is exponentially slow, and impractical for strings of more than a very few characters.


Java recursive code : 
public class LevenshteinDistance {

public static void main(String[] args) {
String src = "hippo";
String target = "elephant";

System.out.println(getMinimumEditDistnace_Recursion(src, target));

}

private static int getMinimumEditDistnace_Recursion(String src,String target) {
if (src == null || src.length() == 0)
return target != null ? target.length() : 0;

if (target == null || target.length() == 0)
return src != null ? src.length() : 0;

char ch1 = src.charAt(0);
char ch2 = target.charAt(0);

int addOne = 0;
if (ch1 != ch2)
addOne = 1;

String deleteCharFromsrc = "";
if (src.length() != 1)
deleteCharFromsrc = src.substring(1);

String deleteCharFromTarget = "";
if (target.length() != 1)
deleteCharFromTarget = target.substring(1);

return minimum(
getMinimumEditDistnace_Recursion(deleteCharFromsrc,
deleteCharFromTarget)
+ addOne, getMinimumEditDistnace_Recursion(src,
deleteCharFromTarget) + 1, getMinimumEditDistnace_Recursion(
deleteCharFromsrc, target) + 1
);
}

private static int minimum(int a, int b, int c) {
if (a <= b && a <= c) {
return a;
} else {
return (b <= a && b <= c) ? b : c;
}
}
}

Above program creating string literals unnecessarly.We can do with out taking subString by tracking index positions.
public class LevenshteinDistance {

public static void main(String[] args) {
System.out.println(getMinimumEditDistnace_Recursion("", "",0,0));
System.out.println(getMinimumEditDistnace_Recursion("", "a",0,0));
System.out.println(getMinimumEditDistnace_Recursion("aaapppp", "",0,0));
System.out.println(getMinimumEditDistnace_Recursion("frog", "fog",0,0));
System.out.println(getMinimumEditDistnace_Recursion("fly", "ant",0,0));
System.out.println(getMinimumEditDistnace_Recursion("elephant", "happo",0,0));
System.out.println(getMinimumEditDistnace_Recursion("hippo", "elephant",0,0));
System.out.println(getMinimumEditDistnace_Recursion("hippo", "zzzzzzzz",0,0));
System.out.println(getMinimumEditDistnace_Recursion("hello", "hallo",0,0));
}

private static int getMinimumEditDistnace_Recursion(String src,String target,int srcIndex, int targetIndex) {

if (src == null || src.length() == 0 || srcIndex>=src.length())
return target != null ? target.length()- targetIndex : 0;

if (target == null || target.length() == 0 || targetIndex>=target.length())
return src != null ? src.length()- srcIndex : 0;

char ch1 = src.charAt(srcIndex);
char ch2 = target.charAt(targetIndex);

int addOne = 0;
if (ch1 != ch2)
addOne = 1;

return minimum(
getMinimumEditDistnace_Recursion(src,target,srcIndex+1,targetIndex+1)+addOne,
getMinimumEditDistnace_Recursion(src,target,srcIndex,targetIndex+1) + 1,
getMinimumEditDistnace_Recursion(src, target,srcIndex+1,targetIndex) + 1
);
}

private static int minimum(int a, int b, int c) {
if (a <= b && a <= c) {
return a;
} else {
return (b <= a && b <= c) ? b : c;
}
}
}

Algorithm_DP :

1)Set n to be the length of s.
  Set m to be the length of t.
  If n = 0, return m and exit.
  If m = 0, return n and exit.
  Construct a matrix containing 0..m rows and 0..n columns.
2)Initialize the first row to 0..n.
  Initialize the first column to 0..m.
3)Examine each character of s (i from 1 to n).
4)Examine each character of t (j from 1 to m).
5)If s[i] equals t[j], the cost is 0.
  If s[i] doesn't equal t[j], the cost is 1.
6)Set cell d[i,j] of the matrix equal to the minimum of:
  a) The cell immediately above plus 1: d[i-1,j] + 1.
  b) The cell immediately to the left plus 1: d[i,j-1] + 1.
  c) The cell diagonally above and to the left plus the cost: d[i-1,j-1] + cost.
7)After the iteration steps (3, 4, 5, 6) are complete, the distance is found in cell d[n,m].

A two-dimensional matrix, dp[0..|s1|,0..|s2|] is used to hold the edit distance values:

dp[i,j] = dp(s1[1..i], s2[1..j])
dp[0,0] = 0
dp[i,0] = i,  i=1..|s1|
dp[0,j] = j,  j=1..|s2|

dp[i,j] = dpin(dp[i-1,j-1]
             + if src[i]=target[j] then 0 else 1 fi,
             dp[i-1, j] + 1,
             dp[i, j-1] + 1 ),  i=1..|s1|, j=1..|s2|


Java Code : 
public class EditDistanceDp {
public static void main(String[] args) {

String src = "hippo";
String target = "elephant";

// Step 1
int srcLength = src.length();
int targetLength = target.length();
if (srcLength == 0) {
System.out.println(targetLength);
return;
}
if (targetLength == 0) {
System.out.println(srcLength);
return;
}
int[][] dp = new int[srcLength + 1][targetLength + 1];

// Step 2
for (int i = 0; i <= srcLength; i++) {
dp[i][0] = i;
}
for (int j = 0; j <= targetLength; j++) {
dp[0][j] = j;
}

// Step 3
int cost;
for (int i = 1; i <= srcLength; i++) {
// Step 4
for (int j = 1; j <= targetLength; j++) {
// Step 5
if (src.charAt(i - 1) == target.charAt(j - 1)) {
cost = 0;
} else {
cost = 1;
}
// Step 6
dp[i][j] = Minimum(dp[i - 1][j] + 1, dp[i][j - 1] + 1,dp[i - 1][j - 1] + cost);
}
}
// Step 7
System.out.println(dp[srcLength][targetLength]);
}

private static int Minimum(int a, int b, int c) {
int temp = a;
if (b < temp) {
temp = b;
}
if (c < temp) {
temp = c;
}
return temp;
}
}

Friday, December 31, 2010

Longest substring Palindrome in a given string

There are N strings that can start with the first letter.
There are N-1 strings that can start with the second letter.
Etc...
There is 1 string that can start with the Nth letter.

So we are going to be checking N(N+1)/2 strings in the worst case.


Write a program which finds the longest palindrome in a given string of characters.

Assumption1.
===========
So if it were of even length then the centre would be i and i+1 for example
KaaK
0123
so centers are 1,2
but for a odd length palindrome the centers are one and the same as in
KapaK
01234
so centers are 2,2

Assumption2:
============
If two strings have the same center and smaller one is not a palindrome then bigger can't be a palindrome

for example:abcddeba
index willb:01234567
since str[3,4] is a palindrome then [2,5] may be a palindrome
but since str[2,5] is not a palindrome [1,6] can't become palindrome.

Logic:
======
Here i take every index in the array as the center of the palindrome.
Now first loop searches for odd lenght palindromes in the string.
Taking the first 0,0 as the centers we try to expand our palindrome till we
encounter the boundaries or a mismatch. In such a way we can eliminate all
the strings with the same base which are not palindromes.



void longestPalindrome(char *input)
{
int len;
int i=0,j=0,k=0,l=0;
int lower=0,upper=0;
len = strlen(input);

/*Odd length Palindromes*/
while(i lessThan len && j lessThan len)
{
k=i;
l=j;
while(( k greaterThan =0 && l lessThan len) && (input[k] == input[l]))
{
if((upper - lower) lessThan = (l-k))
{
lower=k;
upper=l;
}
k--;
l++;
}
i++;
j++;
}

/*Even length Palindromes*/
i = 0;
j = 1;
while(i lessThan len && j lessThan len)
{
k=i;
l=j;
while(( k greaterThan =0 && l lessThan len) && (input[k] == input[l]))
{
if((upper - lower) lessThan = (l-k))
{
lower=k;
upper=l;
}
k--;
l++;
}
i++;
j++;
}

for(i=lower;i lessThan =upper;i++)
{
printf("%c",input[i]);
}
printf("\n");
}


*******************************************************************************
We can solve this in O(n) time using suffix tree algorithm.But the problem with the suffix tree algorithm is,it takes memory to store the tree.

Refer the below urls for more information on suffix tree construction and how it is helpful for operations on strings.

suffix tree construction doc

http://homepage.usask.ca/~ctl271/857/suffix_tree.shtml

http://flexaired.blogspot.com/2011/03/longest-palindrome-in-string.html