The purpose of this project is:
Create a class called IntegerSet that implements Comparable interface to be used in simple set applications. Each object of class IntegerSet can hold positive integers in the range 0 through 255 and most common set operations are available. A set must be represented internally as an int array of ones and zeros (or a boolean array). Array element a[ i ] is 1 if integer i is in the set and array element a[ j ] is 0 if integer j is not in the set.
and then add some member method to modify it.
I am not familiar with "implements Comparable interface," but here is what I got so far. The driver cannot test it, it shows "Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 256"
Can someone help me find out what the problem is? thanks!
import java.util.Arrays;
public class IntegerSet implements Comparable
{
private int L = 256;
private int[] a = new int[L];
public IntegerSet()
{
Arrays.fill(a, 0);
}
public IntegerSet(int n)
{
a[n] = 1;
}
public IntegerSet(int[] n)
{
a = n;
}
public IntegerSet union(IntegerSet other)
{
int[] c = new int[L];
for(int i = 0; i < L; i++)
{
if(this.a[i]==1 || other.a[i] ==1)
c[i] = 1;
else
c[i] = 0;
}
IntegerSet temp = new IntegerSet(c);
return temp;
}
public IntegerSet intersection(IntegerSet other)
{
int[] c = new int[L];
for(int i = 0; i < L; i++)
{
if(this.a[i]==1 && other.a[i] ==1)
c[i] = 1;
else
c[i] = 0;
}
IntegerSet temp = new IntegerSet(c);
return temp;
}
public IntegerSet difference(IntegerSet other)
{
int[] c = new int[L];
for(int i = 0; i < L; i++)
{
if(this.a[i] != other.a[i])
c[i] = 1;
else
c[i] = 0;
}
IntegerSet temp = new IntegerSet(c);
return temp;
}
public IntegerSet insertElement(int k)
{
a[k] = 1;
IntegerSet temp = new IntegerSet(a);
return temp;
}
public IntegerSet removeElement(int k)
{
a[k] = 0;
IntegerSet temp = new IntegerSet(a);
return temp;
}
public boolean isElement(int k)
{
return(a[k] == 1);
}
public String toString()
{
String str = "";
for(int i = 0; i < L; i++)
{
if(a[i] == 1)
str += (i + ", ");
}
return "{" + str + "}";
}
public IntegerSet copy()
{
IntegerSet temp = new IntegerSet(a);
return temp;
}
public boolean subset(IntegerSet other)
{
boolean sub = true;
int i = 0;
while(sub)
{
if(this.a[i] == 1)
{
if(other.a[i] == 1)
sub = true;
else
sub = false;
}
i++;
}
return sub;
}
public boolean superset(IntegerSet other)
{
boolean sup = true;
int i = 0;
while(sup)
{
if(other.a[i] == 1)
{
if(this.a[i] == 1)
sup = true;
else
sup = false;
}
i++;
}
return sup;
}
public void addAll()
{
Arrays.fill(a, 1);
}
public void removeAll()
{
Arrays.fill(a, 0);
}
public int compareTo(Object other)
{
// TODO Auto-generated method stub
return 0;
}
}
and the driver:
public class IntegerSetDriver
{
public static void main(String[] args)
{
IntegerSet s1, s2, s3, s4, s5;
s1 = new IntegerSet(); // s1 is an empty set, {}
s2 = new IntegerSet(5); // s2 is a set with one element, {5}
s1.insertElement(1); // s1 is now {1}
s3 = s1.copy(); // s3 is now {1}
s4 = s1.union(s2); // s4 is now {1, 5} and s1 is still {1}
s5 = s4.insertElement(8).removeElement(5); // s4 is now {1, 8} // s5 references s4
int result = s3.compareTo(s4); // result is -1 (or < 0)
boolean yes = s3.subset(s4); // yes should be true
s5.removeAll(); // s4 and s5 both reference same empty set, {}
s1.removeElement(500); // invalid element so ignore, s1 is still {1}
}
}
You should check your bounds before adding/removing from your int[] a (i.e. 500 is not a valid index).
Also, look at your constructor IntegerSet(input[] n), you cannot just directly "assign" it like that. You need to parse the array and update your local a[] properly.
"n" ranges from 0-255 for values, whereas "a" should only be {1,0}.
A few other things need fixing too.
Related
I have a task to find four unique elements , sum of which is defined. So I have as input data : data array of n elemeents, elements can be duplicated, and 's' is sum.
I have two cycles , first i in values [0, n-1], second j in [i+1, n]. All unique pairs of elements I save in Map , where key is sum and value is Collections of possible elements whats consists that sum. Result is collection of four unique elements of input data array. All actions I do in second cycle :
I check if I already have a differents beetween 's' and data[i]+data[j] ,
2)if I have I check , if data[i] and data[j] doesn't coinside with elements from saved pairs and add to reslut.
Add this pair data[i] + data [ j] to Map with history
I have a Memory Limit in this task and I get over it. Time limit is O(n^2). As I undestand I do some extra actions and save some unnecessary data.I created two object Fourths and Pairs , but they has only primitive fields inside so I thinK what deal is not in that
Here is my code in java:
public class SunForthFAIL {
public static void main(String[] args) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
int n = Integer.parseInt(reader.readLine());
int s = Integer.parseInt(reader.readLine());
int[] data = new int[n];
Set<Forths> result = new HashSet<>();
Map<Integer, Set<Pair>> history = new HashMap<>();
StringTokenizer stringTokenizer = new StringTokenizer(reader.readLine());
for (int i = 0; i < n; i++) {
data[i] = Integer.parseInt(stringTokenizer.nextToken());
}
Arrays.sort(data);
for (int i = 0; i < n - 1; i++) {
for (int j = i + 1; j < n; j++) {
int sum = data[i] + data[j];
int target = s - sum;
if (history.containsKey(target)) {
for (Pair historyPair : history.get(target)) {
if (historyPair.isDiff(i, j)) {
result.add(new Forths(historyPair.getiValue(), historyPair.getjValue(), data[i], data[j]));
}
}
}
if (history.containsKey(sum)) {
history.get(sum).add(new Pair(i, j, data[i], data[j]));
} else {
Set<Pair> set = new HashSet<>();
set.add(new Pair(i, j, data[i], data[j]));
history.put(data[i] + data[j], set);
}
}
}
System.out.println(result.size());
result.stream().sorted(Comparator.comparingInt(Forths::getFirst).thenComparing(Comparator.comparingInt(Forths::getSecond))).forEach(x -> System.out.println(x));
}
}
class Pair {
private int i;
private int j;
private int iValue;
private int jValue;
public int getiValue() {
return iValue;
}
public int getjValue() {
return jValue;
}
public Pair(int i, int j, int iValue, int jValue) {
this.i = i;
this.j = j;
this.iValue = iValue;
this.jValue = jValue;
;
}
public boolean isEquel(int i, int j) {
if (Math.min(iValue, jValue) == Math.min(i, j) &&
Math.max(iValue, jValue) == Math.max(i, j))
return true;
else
return false;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Pair pair = (Pair) o;
if (Math.min(iValue, jValue) == Math.min(pair.iValue, pair.jValue) &&
Math.max(iValue, jValue) == Math.max(pair.iValue, pair.jValue))
return true;
else
return false;
}
#Override
public int hashCode() {
return Objects.hash(Math.min(iValue, jValue) + " " + Math.max(iValue, jValue));
}
public boolean isDiff(int i, int j) {
if (this.i == i || this.i == j || this.j == i || this.j == j)
return false;
else
return true;
}
}
class Forths {
private int first;
private int second;
private int third;
private int forth;
public int getFirst() {
return first;
}
public int getSecond() {
return second;
}
public Forths(int a, int b, int c, int d) {
int[] arr = new int[]{a, b, c, d};
Arrays.sort(arr);
this.first = arr[0];
this.second = arr[1];
this.third = arr[2];
this.forth = arr[3];
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Forths forths = (Forths) o;
return first == forths.first && second == forths.second && third == forths.third && forth == forths.forth;
}
#Override
public int hashCode() {
return Objects.hash(first, second, third, forth);
}
#Override
public String toString() {
return first + " " + second + " " + third + " " + forth;
}
}
In my case, I change the Pair object to int[2], with indexes of pair elements. And memory limit issue is resolved.
''Given two string s and t, write a function to check if s contains all characters of t (in the same order as they are in string t).
Return true or false.
recursion not necessary.
here is the snippet of code that I am writing in java.
problem is for input: string1="st3h5irteuyarh!"
and string2="shrey"
it should return TRUE but it is returning FALSE. Why is that?''
public class Solution {
public static String getString(char x)
{
String s = String.valueOf(x);
return s;
}
public static boolean checkSequence(String s1, String s2)
{
String a = getString(s1.charAt(0));
String b = getString(s2.charAt(0));
for (int i = 1; i < s1.length(); i++)
if (s1.charAt(i) != s1.charAt(i - 1))
{
a += getString(s1.charAt(i));
}
for (int i = 1; i < s2.length(); i++)
if (s2.charAt(i) != s2.charAt(i - 1))
{
b += getString(s2.charAt(i));
}
if (!a.equals(b))
return false;
return true;
}
}
This is a solution:
public class Solution {
public static String getString(char x)
{
String s = String.valueOf(x);
return s;
}
public static boolean checkSequence(String s1, String s2)
{
String a = getString(s1.charAt(0));
String b = getString(s2.charAt(0));
int count = 0;
for (int i = 0; i < s1.length(); i++)
{
if (s1.charAt(i) == s2.charAt(count))
{
count++;
}
if (count == s2.length())
return true;
}
return false;
}
}
Each char of String s1 is compared with a char of String s2 at position count,
if they match count increases: count++;
If count has the length of String 2 all chars matched and true is returned.
there are two problems i can see in that code
1 for (int i = 1; i < s1.length(); i++) you are starting from index 1 but string indexes starts from 0
2 if (s1.charAt(i) != s1.charAt(i - 1)) here you are comparing characters of same strings s1 in other loop also this is the case
please fix these first, then ask again
this could be what you are searching for
public class Solution {
public static boolean checkSequence(String s1, String s2) {
for(char c : s2.toCharArray()) {
if(!s1.contains(c+"")) {
return false;
}
int pos = s1.indexOf(c);
s1 = s1.substring(pos);
}
return true;
}
}
Your approach to solve this problem can be something like this :
Find the smaller string.
Initialise the pointer to starting position of smaller string.
Iterate over the larger string in for loop and keep checking if character is matching.
On match increase the counter of smaller pointer.
while iterating keep checking if smaller pointer has reached to end or not. If yes then return true.
Something like this :
public static boolean checkSequence(String s1, String s2)
{
String smallerString = s1.length()<=s2.length() ? s1 : s2;
String largerString = smallerString.equals(s2) ? s1 : s2;
int smallerStringPointer=0;
for(int i=0;i<largerString.length();i++){
if(smallerString.charAt(smallerStringPointer) == largerString.charAt(i)){
smallerStringPointer++;
}
if(smallerStringPointer == smallerString.length()){
return true;
}
}
return false;
}
public static boolean usingLoops(String str1, String str2) {
int index = -10;
int flag = 0;
for (int i = 0; i < str1.length(); i++) {
flag = 0;
for (int j = i; j < str2.length(); j++) {
if (str1.charAt(i) == str2.charAt(j)) {
if (j < index) {
return false;
}
index = j;
flag = 1;
break;
}
}
if (flag == 0)
return false;
}
return true;
}
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
String str1 = s.nextLine();
String str2 = s.nextLine();
// using loop to solve the problem
System.out.println(usingLoops(str1, str2));
s.close();
}
In interview I got question to sort the array first in LNAME and then FNAME without using any in-built function like(compare, compareTo, Collections.sort).
String NAMES[][]={{"Abse","Blase"},{"Gua","Tysg"},{"Hysdt","Tyser"}};
Unfortunately, I compared the String like below
String fname;
String lname;
for (int i = 0; i < NAMES.length; i++) {
lname = NAMES[i][0];
for (int j = i + 1; j < NAMES.length; j++) {
if (NAMES[j][1] < lname) { // showing compilation error :(
}
}
}
And, I came to know that, It was wrong. Then, how can I compare them without using any in-built function ?
Note: I haven't added full snippet. Just wanted to know, how can we compare String.
According to the String.class compareTo(String s) method states the following. You can probably refer the below snippet but again it will not fulfil your requirement as the compareTo method uses Math function. But I believe this is what the interviewer was looking for.
public int compareTo(String s)
{
int i = value.length;
int j = s.value.length;
int k = Math.min(i, j);
char ac[] = value;
char ac1[] = s.value;
for(int l = 0; l < k; l++)
{
char c = ac[l];
char c1 = ac1[l];
if(c != c1)
return c - c1;
}
return i - j;
}
Pretty hard inteview question. It's more like a school assignment ;)
public void sort() {
String NAMES[][] = {{"Abse", "Blase"}, {"Gua", "Blase"}, {"Gua", "Tysg"}, {"Hysdt", "Tyser"}};
List<String[]> result = new ArrayList<>(3);
for (String[] name : NAMES) {
if (result.isEmpty()) {
result.add(name);
continue;
}
int addAt = 0;
for (String[] sortedName : result) {
if (isBefore(name, sortedName)) {
break;
}
addAt++;
}
result.add(addAt, name);
}
}
private boolean isBefore(String[] name, String[] name2) {
//last name
int position = 0;
char[] lastName1 = name[1].toLowerCase().toCharArray();
char[] lastName2 = name2[1].toLowerCase().toCharArray();
while (lastName1.length > position && lastName2.length > position) {
if (lastName1[position] < lastName2[position]) {
return true;
} else if (lastName1[position] > lastName2[position]) {
return false;
}
position++;
}
position = 0;
char[] firstName1 = name[0].toLowerCase().toCharArray();
char[] firstName2 = name2[0].toLowerCase().toCharArray();
while (firstName1.length > position && firstName2.length > position) {
if (firstName1[position] < firstName2[position]) {
return true;
} else if (firstName1[position] > firstName2[position]) {
return false;
}
position++;
}
//equal so whatever
return false;
}
I have a feeling you would be able to do this with lambdas a lot easier, but I don't really know
< or > operator cannot compare Strings, so we can use it to compare characters.
Maybe implement your own string comparision method. Which checks character by character and returns the String with the highest value.
public String compare(String s1, String s2)
{
for(int i = 0; i < Math.min(s1.length(), s2.length()); i++)
{
if(s1.charAt(i) > s2.charAt(i))
return s1;
}
return s2;
}
To complete the answer to your question.
public class GreatString {
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
String NAMES[][] = { { "Abse", "Blase" }, { "Gua", "Tysg" },
{ "Hysdt", "Tyser" } };
int n = NAMES.length;
for (int i = 0; i < n; i++) {
for (int j = i; j < n; j++) {
if (NAMES[i][0].equals(NAMES[j][0])) {
if (compare(NAMES[i][1], NAMES[j][1])) {
String[] temp = NAMES[i];
NAMES[i] = NAMES[j];
NAMES[j] = temp;
} else {
if (compare(NAMES[i][0], NAMES[j][0])) {
String[] temp = NAMES[i];
NAMES[i] = NAMES[j];
NAMES[j] = temp;
}
}
}
}
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < NAMES[i].length; j++) {
System.out.println(NAMES[i][j]);}}
}
private static boolean compare(String str1, String str2) {
// TODO Auto-generated method stub
int len = str1.length() < str2.length() ? str1.length() : str2.length();
for (int i = 0; i < len; i++) {
if (str1.charAt(i) > str2.charAt(i))
return true;
}
return false;
}
}
I came across a post showing how to arrange char array by alphabet order.
seeing this can be done, I want to output the alphabetical order of each character of the input string, in order of the characters of the input string.
I'm a bit stuck. I can get the string reordered alphabetically, but I don't know what to do next.
example is 'monkey' to '354216'
because 'ekmnoy' e is alphabetically first from the set of given characters so e = 1 , k is the second alpha char when sorted so k = 2, and so on.
if you cannot understand I can provide more example to make things clear out.
Code
String str = "airport";
Character[] chars = new Character[str.length()];
for (int z = 0; z < chars.length; z++) {
chars[z] = str.charAt(z);
}
Arrays.sort(chars, new Comparator<Character>() {
public int compare(Character c1, Character c2) {
int cmp = Character.compare(
Character.toLowerCase(c1.charValue()),
Character.toLowerCase(c2.charValue()));
if (cmp != 0) {
return cmp;
}
return Character.compare(c1.charValue(), c2.charValue());
}
});
StringBuilder sb = new StringBuilder(chars.length);
for (char c : chars) {
sb.append(c);
}
str = sb.toString();
System.out.println(sb);
Output
aioprrt
expected output
Orange -> aegnOr
561432 - 123456
Monkey -> ekMnoy
354216 -> 123456
I dont know what you want to do with double characters, but if you add this few lines to your code at the end you are getting the right result. Iterate over the sorted String and replace the charakters in the original String with their indices in the sorted String.
String originalStr = "airport";
for(int i = 0; i<str.length(); i++) {
originalStr = originalStr.replace(str.charAt(i), String.valueOf(i+1).charAt(0));
}
System.out.println(originalStr);
Output: 1254357
If you want to get the output: 1254367 use replaceFirst:
originalStr = originalStr.replaceFirst(String.valueOf(str.charAt(i)), String.valueOf(i+1));
Input:Orange
Output:561432
Input:Monkey
Output:354216
The whole code:
String str = "airport";
String originalStr = str; //creat a backup of str because you change it in your code
Character[] chars = str.toCharArray();
Arrays.sort(chars, new Comparator<Character>() {
public int compare(Character c1, Character c2) {
int cmp = Character.compare(
Character.toLowerCase(c1.charValue()),
Character.toLowerCase(c2.charValue()));
if (cmp != 0) {
return cmp;
}
return Character.compare(c1.charValue(), c2.charValue());
}
});
str = String.valueOf(chars);
System.out.println(str);
//Iterate over the sorted String and replace the charakters in the original String with their indices in the sorted String
for(int i = 0; i<str.length(); i++) {
originalStr = originalStr.replaceFirst(String.valueOf(str.charAt(i)), String.valueOf(i+1));
}
System.out.println(originalStr);
Once you have arranged the characters in order (in a different array from the original) then create a third array by walking the original string and choosing the index of each character from te sorted string.
input: edcba
sorted: abcde
index: 01234
Pseudocode...
for( int i = 0; i < input.length(); i++ ) {
index[i] = sorted.indexOf(input[i]);
}
Result should be 43210 with the given input.
Note that strings with more than 10 characters will result in ambiguous output, which can be handled by inserting spaces in the output. Example:
abcdefghijk ->
012345678910
You can use this below code:
package Test;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;
public class Arrange {
public static void main(String[] args) {
String str = "money";
List<Test> strs=new LinkedList<Test>();
List<Test> final_result=new LinkedList<Test>();
for(int i=0;i<str.length();i++)
{
Test t=new Test(i, ""+str.charAt(i), 0);
strs.add(t);
}
Collections.sort(strs,new Comparator<Test>() {
#Override
public int compare(Test o1, Test o2) {
return (o1.getS().compareToIgnoreCase(o2.getS()));
}
});
Integer i=1;
for (Test st : strs) {
st.setJ(i);
final_result.add(st);
i++;
}
Collections.sort(final_result,new Comparator<Test>() {
#Override
public int compare(Test o1, Test o2) {
return (o1.getI().compareTo(o2.getI()));
}
});
for (Test test : final_result) {
System.out.println(test.getJ());
}
}
}
class Test{
private Integer i;
private String s;
private Integer j;
public Test() {
// TODO Auto-generated constructor stub
}
public Test(Integer i, String s, Integer j) {
super();
this.i = i;
this.s = s;
this.j = j;
}
public Integer getI() {
return i;
}
public void setI(Integer i) {
this.i = i;
}
public String getS() {
return s;
}
public void setS(String s) {
this.s = s;
}
public Integer getJ() {
return j;
}
public void setJ(Integer j) {
this.j = j;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((i == null) ? 0 : i.hashCode());
result = prime * result + ((j == null) ? 0 : j.hashCode());
result = prime * result + ((s == null) ? 0 : s.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Test other = (Test) obj;
if (i == null) {
if (other.i != null)
return false;
} else if (!i.equals(other.i))
return false;
if (j == null) {
if (other.j != null)
return false;
} else if (!j.equals(other.j))
return false;
if (s == null) {
if (other.s != null)
return false;
} else if (!s.equals(other.s))
return false;
return true;
}
}
I am struggling with a "find supersequence" algorithm.
The input is for set of strings
String A = "caagccacctacatca";
String B = "cgagccatccgtaaagttg";
String C = "agaacctgctaaatgctaga";
the result would be properly aligned set of strings (and next step should be merge)
String E = "ca ag cca cc ta cat c a";
String F = "c gag ccat ccgtaaa g tt g";
String G = " aga acc tgc taaatgc t a ga";
Thank you for any advice (I am sitting on this task for more than a day)
after merge the superstring would be
cagagaccatgccgtaaatgcattacga
The definition of supersequence in "this case" would be something like
The string R is contained in supersequence S if and only if all characters in a string R are present in supersequence S in the order in which they occur in the input sequence R.
The "solution" i tried (and again its the wrong way of doing it) is:
public class Solution4
{
static boolean[][] map = null;
static int size = 0;
public static void main(String[] args)
{
String A = "caagccacctacatca";
String B = "cgagccatccgtaaagttg";
String C = "agaacctgctaaatgctaga";
Stack data = new Stack();
data.push(A);
data.push(B);
data.push(C);
Stack clone1 = data.clone();
Stack clone2 = data.clone();
int length = 26;
size = max_size(data);
System.out.println(size+" "+length);
map = new boolean[26][size];
char[] result = new char[size];
HashSet<String> chunks = new HashSet<String>();
while(!clone1.isEmpty())
{
String a = clone1.pop();
char[] residue = make_residue(a);
System.out.println("---");
System.out.println("OLD : "+a);
System.out.println("RESIDUE : "+String.valueOf(residue));
String[] r = String.valueOf(residue).split(" ");
for(int i=0; i<r.length; i++)
{
if(r[i].equals(" ")) continue;
//chunks.add(spaces.substring(0,i)+r[i]);
chunks.add(r[i]);
}
}
for(String chunk : chunks)
{
System.out.println("CHUNK : "+chunk);
}
}
static char[] make_residue(String candidate)
{
char[] result = new char[size];
for(int i=0; i<candidate.length(); i++)
{
int pos = find_position_for(candidate.charAt(i),i);
for(int j=i; j<pos; j++) result[j]=' ';
if(pos==-1) result[candidate.length()-1] = candidate.charAt(i);
else result[pos] = candidate.charAt(i);
}
return result;
}
static int find_position_for(char character, int offset)
{
character-=((int)'a');
for(int i=offset; i<size; i++)
{
// System.out.println("checking "+String.valueOf((char)(character+((int)'a')))+" at "+i);
if(!map[character][i])
{
map[character][i]=true;
return i;
}
}
return -1;
}
static String move_right(String a, int from)
{
return a.substring(0, from)+" "+a.substring(from);
}
static boolean taken(int character, int position)
{ return map[character][position]; }
static void take(char character, int position)
{
//System.out.println("taking "+String.valueOf(character)+" at "+position+" (char_index-"+(character-((int)'a'))+")");
map[character-((int)'a')][position]=true;
}
static int max_size(Stack stack)
{
int max=0;
while(!stack.isEmpty())
{
String s = stack.pop();
if(s.length()>max) max=s.length();
}
return max;
}
}
Finding any common supersequence is not a difficult task:
In your example possible solution would be something like:
public class SuperSequenceTest {
public static void main(String[] args) {
String A = "caagccacctacatca";
String B = "cgagccatccgtaaagttg";
String C = "agaacctgctaaatgctaga";
int iA = 0;
int iB = 0;
int iC = 0;
char[] a = A.toCharArray();
char[] b = B.toCharArray();
char[] c = C.toCharArray();
StringBuilder sb = new StringBuilder();
while (iA < a.length || iB < b.length || iC < c.length) {
if (iA < a.length && iB < b.length && iC < c.length && (a[iA] == b[iB]) && (a[iA] == c[iC])) {
sb.append(a[iA]);
iA++;
iB++;
iC++;
}
else if (iA < a.length && iB < b.length && a[iA] == b[iB]) {
sb.append(a[iA]);
iA++;
iB++;
}
else if (iA < a.length && iC < c.length && a[iA] == c[iC]) {
sb.append(a[iA]);
iA++;
iC++;
}
else if (iB < b.length && iC < c.length && b[iB] == c[iC]) {
sb.append(b[iB]);
iB++;
iC++;
} else {
if (iC < c.length) {
sb.append(c[iC]);
iC++;
}
else if (iB < b.length) {
sb.append(b[iB]);
iB++;
} else if (iA < a.length) {
sb.append(a[iA]);
iA++;
}
}
}
System.out.println("SUPERSEQUENCE " + sb.toString());
}
}
However the real problem to solve is to find the solution for the known problem of Shortest Common Supersequence http://en.wikipedia.org/wiki/Shortest_common_supersequence,
which is not that easy.
There is a lot of researches which concern the topic.
See for instance:
http://www.csd.uwo.ca/~lila/pdfs/Towards%20a%20DNA%20solution%20to%20the%20Shortest%20Common%20Superstring%20Problem.pdf
http://www.ncbi.nlm.nih.gov/pubmed/14534185
You can try finding the shortest combination like this
static final char[] CHARS = "acgt".toCharArray();
public static void main(String[] ignored) {
String A = "caagccacctacatca";
String B = "cgagccatccgtaaagttg";
String C = "agaacctgctaaatgctaga";
String expected = "cagagaccatgccgtaaatgcattacga";
List<String> ABC = new Combination(A, B, C).findShortest();
System.out.println("expected: " + expected.length());
System.out.println("Merged: " + ABC.get(0).length() + " " + ABC);
}
static class Combination {
int shortest = Integer.MAX_VALUE;
List<String> shortestStr = new ArrayList<>();
char[][] chars;
int[] pos;
int count = 0;
Combination(String... strs) {
chars = new char[strs.length][];
pos = new int[strs.length];
for (int i = 0; i < strs.length; i++) {
chars[i] = strs[i].toCharArray();
}
}
public List<String> findShortest() {
findShortest0(new StringBuilder(), pos);
return shortestStr;
}
private void findShortest0(StringBuilder sb, int[] pos) {
if (allDone(pos)) {
if (sb.length() < shortest) {
shortestStr.clear();
shortest = sb.length();
}
if (sb.length() <= shortest)
shortestStr.add(sb.toString());
count++;
if (++count % 100 == 1)
System.out.println("Searched " + count + " shortest " + shortest);
return;
}
if (sb.length() + maxLeft(pos) > shortest)
return;
int[] pos2 = new int[pos.length];
int i = sb.length();
sb.append(' ');
for (char c : CHARS) {
if (!tryChar(pos, pos2, c)) continue;
sb.setCharAt(i, c);
findShortest0(sb, pos2);
}
sb.setLength(i);
}
private int maxLeft(int[] pos) {
int maxLeft = 0;
for (int i = 0; i < pos.length; i++) {
int left = chars[i].length - pos[i];
if (left > maxLeft)
maxLeft = left;
}
return maxLeft;
}
private boolean allDone(int[] pos) {
for (int i = 0; i < chars.length; i++)
if (pos[i] < chars[i].length)
return false;
return true;
}
private boolean tryChar(int[] pos, int[] pos2, char c) {
boolean matched = false;
for (int i = 0; i < chars.length; i++) {
pos2[i] = pos[i];
if (pos[i] >= chars[i].length) continue;
if (chars[i][pos[i]] == c) {
pos2[i]++;
matched = true;
}
}
return matched;
}
}
prints many solutions which are shorter than the one suggested.
expected: 28
Merged: 27 [acgaagccatccgctaaatgctatcga, acgaagccatccgctaaatgctatgca, acgaagccatccgctaacagtgctaga, acgaagccatccgctaacatgctatga, acgaagccatccgctaacatgcttaga, acgaagccatccgctaacatgtctaga, acgaagccatccgctacaagtgctaga, acgaagccatccgctacaatgctatga, acgaagccatccgctacaatgcttaga, acgaagccatccgctacaatgtctaga, acgaagccatcgcgtaaatgctatcga, acgaagccatcgcgtaaatgctatgca, acgaagccatcgcgtaacagtgctaga, acgaagccatcgcgtaacatgctatga, acgaagccatcgcgtaacatgcttaga, acgaagccatcgcgtaacatgtctaga, acgaagccatcgcgtacaagtgctaga, acgaagccatcgcgtacaatgctatga, acgaagccatcgcgtacaatgcttaga, acgaagccatcgcgtacaatgtctaga, acgaagccatgccgtaaatgctatcga, acgaagccatgccgtaaatgctatgca, acgaagccatgccgtaacagtgctaga, acgaagccatgccgtaacatgctatga, acgaagccatgccgtaacatgcttaga, acgaagccatgccgtaacatgtctaga, acgaagccatgccgtacaagtgctaga, acgaagccatgccgtacaatgctatga, acgaagccatgccgtacaatgcttaga, acgaagccatgccgtacaatgtctaga, cagaagccatccgctaaatgctatcga, cagaagccatccgctaaatgctatgca, cagaagccatccgctaacagtgctaga, cagaagccatccgctaacatgctatga, cagaagccatccgctaacatgcttaga, cagaagccatccgctaacatgtctaga, cagaagccatccgctacaagtgctaga, cagaagccatccgctacaatgctatga, cagaagccatccgctacaatgcttaga, cagaagccatccgctacaatgtctaga, cagaagccatcgcgtaaatgctatcga, cagaagccatcgcgtaaatgctatgca, cagaagccatcgcgtaacagtgctaga, cagaagccatcgcgtaacatgctatga, cagaagccatcgcgtaacatgcttaga, cagaagccatcgcgtaacatgtctaga, cagaagccatcgcgtacaagtgctaga, cagaagccatcgcgtacaatgctatga, cagaagccatcgcgtacaatgcttaga, cagaagccatcgcgtacaatgtctaga, cagaagccatgccgtaaatgctatcga, cagaagccatgccgtaaatgctatgca, cagaagccatgccgtaacagtgctaga, cagaagccatgccgtaacatgctatga, cagaagccatgccgtaacatgcttaga, cagaagccatgccgtaacatgtctaga, cagaagccatgccgtacaagtgctaga, cagaagccatgccgtacaatgctatga, cagaagccatgccgtacaatgcttaga, cagaagccatgccgtacaatgtctaga, cagagaccatccgctaaatgctatcga, cagagaccatccgctaaatgctatgca, cagagaccatccgctaacagtgctaga, cagagaccatccgctaacatgctatga, cagagaccatccgctaacatgcttaga, cagagaccatccgctaacatgtctaga, cagagaccatccgctacaagtgctaga, cagagaccatccgctacaatgctatga, cagagaccatccgctacaatgcttaga, cagagaccatccgctacaatgtctaga, cagagaccatcgcgtaaatgctatcga, cagagaccatcgcgtaaatgctatgca, cagagaccatcgcgtaacagtgctaga, cagagaccatcgcgtaacatgctatga, cagagaccatcgcgtaacatgcttaga, cagagaccatcgcgtaacatgtctaga, cagagaccatcgcgtacaagtgctaga, cagagaccatcgcgtacaatgctatga, cagagaccatcgcgtacaatgcttaga, cagagaccatcgcgtacaatgtctaga, cagagaccatgccgtaaatgctatcga, cagagaccatgccgtaaatgctatgca, cagagaccatgccgtaacagtgctaga, cagagaccatgccgtaacatgctatga, cagagaccatgccgtaacatgcttaga, cagagaccatgccgtaacatgtctaga, cagagaccatgccgtacaagtgctaga, cagagaccatgccgtacaatgctatga, cagagaccatgccgtacaatgcttaga, cagagaccatgccgtacaatgtctaga, cagagccatcctagctaaagtgctaga, cagagccatcctagctaaatgctatga, cagagccatcctagctaaatgcttaga, cagagccatcctagctaaatgtctaga, cagagccatcctgactaaagtgctaga, cagagccatcctgactaaatgctatga, cagagccatcctgactaaatgcttaga, cagagccatcctgactaaatgtctaga, cagagccatcctgctaaatgctatcga, cagagccatcctgctaaatgctatgca, cagagccatcctgctaacagtgctaga, cagagccatcctgctaacatgctatga, cagagccatcctgctaacatgcttaga, cagagccatcctgctaacatgtctaga, cagagccatcctgctacaagtgctaga, cagagccatcctgctacaatgctatga, cagagccatcctgctacaatgcttaga, cagagccatcctgctacaatgtctaga]