Assuming "A B C D" to be a sentence, is there any dedicated name for two following string deconstructions :
1)
size:3 <=> {"ABC", "BCD"}
size:2 <=> {"AB","BC", "CD"}
2)
size:3 <=> {"ABC", "ABD", "BCD"}
size:2 <=> {"AB","AC", "AD", "BC", "BD", "CD"}
Please, note that we never permute elements...
Thank you in advance,
-Bast
Like java code
String sequence = "A B C D";
public List createConventions(String sequence,int mode) {
List<String> result = new ArrayList<>();
String[] elements = sequence.split(" ");
for (int i = 0; i < elements.length; i++) {
for (int j = i + 1; j < elements.length; j++) {
if (mode == 1) {
result.add(elements[i] + elements[j]);
} else if (mode == 2) {
for (int k = j + 1; k < elements.length; k++) {
result.add(elements[i] + elements[j] + elements[k]);
}
}
}
}
return result;
}
Related
Hi I was trying to solve the interleaving strings problem.Here is the detailed explanation of the problem. https://practice.geeksforgeeks.org/problems/interleaved-strings/1
I was trying using lcs but it was not passing leetcode cases. Here is my Code:-
(I am taking lcs from start and end)
class Solution {
public boolean isInterLeave(String a, String b, String c) {
StringBuffer s=new StringBuffer();
StringBuffer s1=new StringBuffer();
StringBuffer s2=new StringBuffer();
StringBuffer s4=new StringBuffer();
int m=a.length();
int n=c.length();
int q=b.length();
if(n!=m+q){
return false;
}
LinkedHashSet<Integer> res2= new LinkedHashSet<Integer>();
res2= lcs(a,c,m,n);
LinkedHashSet<Integer> res4= new LinkedHashSet<Integer>();
res4= lcs(b,c,q,n);
for(int i=0;i<n;i++){
if(res2.contains(i)==false){
s.append(c.charAt(i));
}
}
for(int i=0;i<n;i++){
if(res4.contains(i)==false){
s1.append(c.charAt(i));
}
}
LinkedHashSet<Integer> res5= new LinkedHashSet<Integer>();
res5= LCS(a,c,m,n);
for(int i=0;i<n;i++){
if(res5.contains(i)==false){
s2.append(c.charAt(i));
}
} LinkedHashSet<Integer> res6= new LinkedHashSet<Integer>();
res6= LCS(b,c,q,n);
for(int i=0;i<n;i++){
if(res6.contains(i)==false){
s4.append(c.charAt(i));
}
}
String z=s.toString();
String u=s1.toString();
String v=s2.toString();
String w=s4.toString();
if( (b.equals(z)==true || a.equals(u)==true) || ( b.equals(v)==true || a.equals(w)==true)){
return true;
}
else{
return false;
}
}
public static LinkedHashSet<Integer> lcs(String X, String Y, int m, int n)
{
int[][] L = new int[m+1][n+1];
// Following steps build L[m+1][n+1] in bottom up fashion. Note
// that L[i][j] contains length of LCS of X[0..i-1] and Y[0..j-1]
for (int i=0; i<=m; i++)
{
for (int j=0; j<=n; j++)
{
if (i == 0 || j == 0)
L[i][j] = 0;
else if (X.charAt(i-1) == Y.charAt(j-1))
L[i][j] = L[i-1][j-1] + 1;
else
L[i][j] = Math.max(L[i-1][j], L[i][j-1]);
}
}
// Following code is used to print LCS
// Create a character array to store the lcs string
LinkedHashSet<Integer> linkedset =
new LinkedHashSet<Integer>();
// Start from the right-most-bottom-most corner and
// one by one store characters in lcs[]
int i=1;
int j=1;
while (i <= m && j <= n)
{
// If current character in X[] and Y are same, then
// current character is part of LCS
if (X.charAt(i-1) == Y.charAt(j-1))
{
// Put current character in result
linkedset.add(j-1);
// reduce values of i, j and index
i++;
j++;
}
// If not same, then find the larger of two and
// go in the direction of larger value
else if (L[i-1][j] > L[i][j-1])
i++;
else
j++;
}
return linkedset;
}
public static LinkedHashSet<Integer> LCS(String X, String Y, int m, int n)
{
int[][] L = new int[m+1][n+1];
// Following steps build L[m+1][n+1] in bottom up fashion. Note
// that L[i][j] contains length of LCS of X[0..i-1] and Y[0..j-1]
for (int i=0; i<=m; i++)
{
for (int j=0; j<=n; j++)
{
if (i == 0 || j == 0)
L[i][j] = 0;
else if (X.charAt(i-1) == Y.charAt(j-1))
L[i][j] = L[i-1][j-1] + 1;
else
L[i][j] = Math.max(L[i-1][j], L[i][j-1]);
}
}
// Following code is used to print LCS
// Create a character array to store the lcs string
LinkedHashSet<Integer> linkedset =
new LinkedHashSet<Integer>();
// Start from the right-most-bottom-most corner and
// one by one store characters in lcs[]
int i = m;
int j = n;
while (i > 0 && j > 0)
{
// If current character in X[] and Y are same, then
// current character is part of LCS
if (X.charAt(i-1) == Y.charAt(j-1))
{
// Put current character in result
linkedset.add(j-1);
// reduce values of i, j and index
i--;
j--;
}
// If not same, then find the larger of two and
// go in the direction of larger value
else if (L[i-1][j] > L[i][j-1])
i--;
else
j--;
}
return linkedset;
}
}
Can anyone suggest an LCS approach to this problem?.My code is not passing the following test case
"cacabcbaccbbcbb" -String A
"acaaccaacbbbabbacc"-String B
"accacaabcbacaccacacbbbbcbabbbbacc"-String C
This will be the LCS+DP approach. Try it out:
class Solution {
public boolean isInterleave(String s1, String s2, String s3) {
int m = s1.length(), n = s2.length();
if (n + m != s3.length()) return false;
if (s3.length() == 0) return true;
boolean[][] dp = new boolean[m+1][n+1];
dp[0][0] = true;
for (int i = 0; i <= m; i++) {
if (s1.substring(0, i).equals(s3.substring(0, i)))
dp[i][0] = true;
else
dp[i][0] = false;
}
for (int j = 0; j <= n; j++) {
if (s2.substring(0, j).equals(s3.substring(0, j)))
dp[0][j] = true;
else
dp[0][j] = false;
}
for (int i = 1; i <= m; i++) {
for (int j = 1; j <= n; j++) {
dp[i][j] = (dp[i-1][j] && s1.charAt(i-1) == s3.charAt(i+j-1))
|| (dp[i][j-1] && s2.charAt(j-1) == s3.charAt(i+j-1));
}
}
return dp[m][n];
}
}
give a string s, encode it by the format: "aaa" to "3[a]". The length of encoded string should the shortest.
example: "abbabb" to "2[a2[b]]"
update: suppose the string only contains lowercase letters
update: here is my code in c++, but it's slow. I know one of the improvement is using KMP to compute if the current string is combined by a repeat string.
// this function is used to check if a string is combined by repeating a substring.
// Also Here can be replaced by doing KMP algorithm for whole string to improvement
bool checkRepeating(string& s, int l, int r, int start, int end){
if((end-start+1)%(r-l+1) != 0)
return false;
int len = r-l+1;
bool res = true;
for(int i=start; i<=end; i++){
if(s[(i-start)%len+l] != s[i]){
res = false;
break;
}
}
return res;
}
// this function is used to get the length of the current number
int getLength(int l1, int l2){
return (int)(log10(l2/l1+1)+1);
}
string shortestEncodeString(string s){
int len = s.length();
vector< vector<int> > res(len, vector<int>(len, 0));
//Initial the matrix
for(int i=0; i<len; i++){
for(int j=0; j<=i; j++){
res[j][i] = i-j+1;
}
}
unordered_map<string, string> record;
for(int i=0; i<len; i++){
for(int j=i; j>=0; j--){
string temp = s.substr(j, i-j+1);
/* if the current substring has showed before, then no need to compute again
* Here is a example for this part: if the string is "abcabc".
* if we see the second "abc", then no need to compute again, just use the
* result from first "abc".
**/
if(record.find(temp) != record.end()){
res[j][i] = record[temp].size();
continue;
}
string ans = temp;
for(int k=j; k<i; k++){
string str1 = s.substr(j, k-j+1);
string str2 = s.substr(k+1, i-k);
if(res[j][i] > res[j][k] + res[k+1][i]){
res[j][i] = res[j][k]+res[k+1][i];
ans = record[str1] + record[str2];
}
if(checkRepeating(s, j, k, k+1, i) == true && res[j][i] > 2+getLength(k-j+1, i-k)+res[j][k]){
res[j][i] = 2+getLength(k-j+1, i-k)+res[j][k];
ans = to_string((i-j+1)/(k-j+1)) + '[' + record[str1] +']';
}
}
record[temp] = ans;
}
}
return record[s];
}
With very little to start with in terms of a question statement, I took a quick stab at this using JavaScript because it's easy to demonstrate. The comments are in the code, but basically there are alternating stages of joining adjacent elements, run-length checking, joining adjacent elements, and on and on until there is only one element left - the final encoded value.
I hope this helps.
function encode(str) {
var tmp = str.split('');
var arr = [];
do {
if (tmp.length === arr.length) {
// Join adjacent elements
arr.length = 0;
for (var i = 0; i < tmp.length; i += 2) {
if (i < tmp.length - 1) {
arr.push(tmp[i] + tmp[i + 1]);
} else {
arr.push(tmp[i]);
}
}
tmp.length = 0;
} else {
// Swap arrays and clear tmp
arr = tmp.slice();
tmp.length = 0;
}
// Build up the run-length strings
for (var i = 0; i < arr.length;) {
var runlength = runLength(arr, i);
if (runlength > 1) {
tmp.push(runlength + '[' + arr[i] + ']');
} else {
tmp.push(arr[i]);
}
i += runlength;
}
console.log(tmp);
} while (tmp.length > 1);
return tmp.join();
}
// Get the longest run length from a given index
function runLength(arr, ind) {
var count = 1;
for (var i = ind; i < arr.length - 1; i++) {
if (arr[i + 1] === arr[ind]) {
count++;
} else {
break;
}
}
return count;
}
<input id='inp' value='abbabb'>
<button type="submit" onClick='javascript:document.getElementById("result").value=encode(document.getElementById("inp").value)'>Encode</button>
<br>
<input id='result' value='2[a2[b]]'>
class Program
{
static void Main(string[] args)
{
Console.Write("Enter Word : ");
string word = Console.ReadLine();
for (var i = 0; i < word.Length; i++)
{
var check = true;
var count = 0;
for (var k = i - 1; k <= 0; k--)
{
if (word[k] == word[i]) check = false;
}
if (check)
{
for (var j = i; j<= word.Length; j++)
{
if (word[i] == word[j]) count++;
}
Console.WriteLine(word[i] + " Occurs at " + count + " places.");
}
}
Console.ReadLine();
}
}
I have tried this one but not working.
The problem is that check is set to false if the string contains two adjacent identical characters. So if (check) {...} won't be executed, if this is the case. Another problem is that you set k to string position -1 in the first iteration of for (var k = i - 1; k <= 0; k--). If i=0, then k will be -1. You also need only one inner loop.
Here is a possible solution, although slightly different than your's.
class Program
{
static void Main(string[] args)
{
Console.Write("Enter Word : ");
string word = Console.ReadLine();
int i = 0;
while (i < word.Length)
{
int count = 1;
for (int k = i+1; k < word.Length; k++)
if (word[i] == word[k])
count++;
if (count>1)
{
Console.WriteLine(word[i] + " Occurs at " + count + " places.");
}
i += count; // continue next char or after after repeated chars
}
Console.ReadLine();
}
}
Cannot figure out what is wrong here. Any thoughts?
for( int j = i + 1; j < dt.Rows.Count; j++)
{
if (dt.Rows[j]["DUPE"] == "X") { continue; }
if (dt.Rows[i][0].ToString().Trim()==dt.Rows[j][0].ToString().Trim())
{
dt.Rows[i]["On Hand"] = Convert.ToInt64(dt.Rows[i]["On Hand"]) + Convert.ToInt64(dt.Rows[j]["On Hand"]);
dt.Rows[j]["DUPE"] = "X";
}
}
Can someone explain to me how to solve the substring problem iteratively?
The problem: given two strings S=S1S2S3…Sn and T=T1T2T3…Tm, with m is less than or equal to n, determine if T is a substring of S.
Here's a list of string searching algorithms
Depending on your needs, a different algorithm may be a better fit, but Boyer-Moore is a popular choice.
A naive algorithm would be to test at each position 0 < i ≤ n-m of S if Si+1Si+2…Si+m=T1T2…Tm. For n=7 and m=5:
i=0: S1S2S3S4S5S6S7
| | | | |
T1T2T3T4T5
i=1: S1S2S3S4S5S6S7
| | | | |
T1T2T3T4T5
i=2: S1S2S3S4S5S6S7
| | | | |
T1T2T3T4T5
The algorithm in pseudo-code:
// we just need to test if n ≤ m
IF n > m:
// for each offset on that T can start to be substring of S
FOR i FROM 0 TO n-m:
// compare every character of T with the corresponding character in S plus the offset
FOR j FROM 1 TO m:
// if characters are equal
IF S[i+j] == T[j]:
// if we’re at the end of T, T is a substring of S
IF j == m:
RETURN true;
ENDIF;
ELSE:
BREAK;
ENDIF;
ENDFOR;
ENDFOR;
ENDIF;
RETURN false;
Not sure what language you're working in, but here's an example in C#. It's a roughly n2 algorithm, but it will get the job done.
bool IsSubstring (string s, string t)
{
for (int i = 0; i <= (s.Length - t.Length); i++)
{
bool found = true;
for (int j = 0; found && j < t.Length; j++)
{
if (s[i + j] != t[j])
found = false;
}
if (found)
return true;
}
return false;
}
if (T == string.Empty) return true;
for (int i = 0; i <= S.Length - T.Length; i++) {
for (int j = 0; j < T.Length; j++) {
if (S[i + j] == T[j]) {
if (j == (T.Length - 1)) return true;
}
else break;
}
}
return false;
It would go something like this:
m==0? return true
cs=0
ct=0
loop
cs>n-m? break
char at cs+ct in S==char at ct in T?
yes:
ct=ct+1
ct==m? return true
no:
ct=0
cs=cs+1
end loop
return false
This may be redundant with the above list of substring algorithms, but I was always amused by KMP (http://en.wikipedia.org/wiki/Knuth–Morris–Pratt_algorithm)
// runs in best case O(n) where no match, worst case O(n2) where strings match
var s = "hippopotumus"
var t = "tum"
for(var i=0;i<s.length;i++)
if(s[i]==t[0])
for(var ii=i,iii=0; iii<t.length && i<s.length; ii++, iii++){
if(s[ii]!=t[iii]) break
else if (iii==t.length-1) console.log("yay found it at index: "+i)
}
Here is my PHP variation that includes a check to make sure the Needle does not exceed the Haystacks length during the search.
<?php
function substring($haystack,$needle) {
if("" == $needle) { return true; }
echo "Haystack:\n$haystack\n";
echo "Needle:\n$needle\n";
for($i=0,$len=strlen($haystack);$i<$len;$i++){
if($needle[0] == $haystack[$i]) {
$found = true;
for($j=0,$slen=strlen($needle);$j<$slen;$j++) {
if($j >= $len) { return false; }
if($needle[$j] != $haystack[$i+$j]) {
$found = false;
continue;
}
}
if($found) {
echo " . . . . . . SUCCESS!!!! startPos: $i\n";
return true;
}
}
}
echo " . . . . . . FAILURE!\n" ;
return false;
}
assert(substring("haystack","hay"));
assert(!substring("ack","hoy"));
assert(substring("hayhayhay","hayhay"));
assert(substring("mucho22","22"));
assert(!substring("str","string"));
?>
Left in some echo's. Remove if they offend you!
Is a O(n*m) algorithm, where n and m are the size of each string.
In C# it would be something similar to:
public static bool IsSubtring(char[] strBigger, char[] strSmall)
{
int startBigger = 0;
while (startBigger <= strBigger.Length - strSmall.Length)
{
int i = startBigger, j = 0;
while (j < strSmall.Length && strSmall[j] == strBigger[i])
{
i++;
j++;
}
if (j == strSmall.Length)
return true;
startBigger++;
}
return false;
}
I know I'm late to the game but here is my version of it (in C#):
bool isSubString(string subString, string supraString)
{
for (int x = 0; x <= supraString.Length; x++)
{
int counter = 0;
if (subString[0] == supraString[x]) //find initial match
{
for (int y = 0; y <= subString.Length; y++)
{
if (subString[y] == supraString[y+x])
{
counter++;
if (counter == subString.Length)
{
return true;
}
}
}
}
}
return false;
}
Though its pretty old post, I am trying to answer it. Kindly correct me if anything is wrong,
package com.amaze.substring;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class CheckSubstring {
/**
* #param args
* #throws IOException
*/
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.println("Please enter the main string");
String mainStr = br.readLine();
System.out.println("Enter the substring that has to be searched");
String subStr = br.readLine();
char[] mainArr = new char[mainStr.length()];
mainArr = mainStr.toCharArray();
char[] subArr = new char[subStr.length()];
subArr = subStr.toCharArray();
boolean tracing = false;
//System.out.println("Length of substring is "+subArr.length);
int j = 0;
for(int i=0; i<mainStr.length();i++){
if(!tracing){
if(mainArr[i] == subArr[j]){
tracing = true;
j++;
}
} else {
if (mainArr[i] == subArr[j]){
//System.out.println(mainArr[i]);
//System.out.println(subArr[j]);
j++;
System.out.println("Value of j is "+j);
if((j == subArr.length)){
System.out.println("SubString found");
return;
}
} else {
j=0;
tracing = false;
}
}
}
System.out.println("Substring not found");
}
}