Knuth Morris Pratt application no error but not working - java

Here's my application
"Textform", take value from the searchbox.
"listKamus", take value from the array. Then "player name", change it value to string.
"KMP.knutMorris(textform, playerName)", send textform, playerName value to knutMorris class
MAIN CLASS
public void onTextChanged(CharSequence s, int arg1, int arg2, int arg3)
{
String textform = s.toString();
searchResults.clear();
for(int i=0;i<listKamus.size();i++)
{
String playerName=listKamus.get(i).toString();
KMP.knutMorris(textform, playerName);
if(KMP.value==1){
searchResults.add(listKamus.get(i));
}
}
adapter.notifyDataSetChanged();
}
KMP CLASS
public class KMP {
/** Failure array **/
private int[] failure;
public static int value;
/** Constructor **/
public KMP(String text, String pat)
{
/** pre construct failure array for a pattern **/
failure = new int[pat.length()];
fail(pat);
/** find match **/
int pos = posMatch(text, pat);
if (pos >= 0)
{
KMP.value = 1;
}
}
/** Failure function for a pattern **/
private void fail(String pat)
{
int n = pat.length();
failure[0] = -1;
for (int j = 1; j < n; j++)
{
int i = failure[j - 1];
while ((pat.charAt(j) != pat.charAt(i + 1)) && i >= 0)
i = failure[i];
if (pat.charAt(j) == pat.charAt(i + 1))
failure[j] = i + 1;
else
failure[j] = -1;
}
}
/** Function to find match for a pattern **/
private int posMatch(String text, String pat)
{
int i = 0, j = 0;
int lens = text.length();
int lenp = pat.length();
while (i < lens && j < lenp)
{
if (text.charAt(i) == pat.charAt(j))
{
i++;
j++;
}
else if (j == 0)
i++;
else
j = failure[j - 1] + 1;
}
return ((j == lenp) ? (i - lenp) : -1);
}
/** Main Function **/
public static void knutMorris(String textform, String isidatabase)
{
String text = textform;
String pattern = isidatabase;
KMP kmp = new KMP(text, pattern);
}
I want when people type on the searchbox it shows the right list of array.
I think the error one is here
MAIN CLASS
if(KMP.value==1){
searchResults.add(listKamus.get(i));
}
Or here
KMP CLASS
if (pos >= 0)
{
KMP.value = 1;
}
Can anyone tell me how to fix this ?

Related

Binary heap output not as expected

I have a homework that the teacher test if it's corrects by checking it's output using this website moodle.caseine.org, so to test my code the program execute these lines and compare the output with the expected one, this is the test :
Tas t = new Tas();
Random r = new Random(123);
for(int i =0; i<10000;i++)t.inser(r.nextInt());
for(int i =0;i<10000;i++)System.out.println(t.supprMax());
System.out.println(t);
And my Heap (Tas) class:
package td1;
import java.util.ArrayList;
import java.util.List;
public class Tas {
private List<Integer> t;
public Tas() {
t = new ArrayList<>();
}
public Tas(ArrayList<Integer> tab) {
t = new ArrayList<Integer>(tab);
}
public static int getFilsGauche(int i) {
return 2 * i + 1;
}
public static int getFilsDroit(int i) {
return 2 * i + 2;
}
public static int getParent(int i) {
return (i - 1) / 2;
}
public boolean estVide() {
return t.isEmpty();
}
#Override
public String toString() {
String str = "";
int size = t.size();
if (size > 0) {
str += "[" + t.get(0);
str += toString(0);
str += "]";
}
return str;
}
public boolean testTas() {
int size = t.size();
int check = 0;
if (size > 0) {
for (int i = 0; i < t.size(); i++) {
if (getFilsGauche(i) < size) {
if (t.get(i) < t.get(getFilsGauche(i))) {
check++;
}
}
if (getFilsDroit(i) < size) {
if (t.get(i) < t.get(getFilsDroit(i))) {
check++;
}
}
}
}
return check == 0;
}
public String toString(int i) {
String str = "";
int size = t.size();
if (getFilsGauche(i) < size) {
str += "[";
str += t.get(getFilsGauche(i));
str += toString(getFilsGauche(i));
str += "]";
}
if (getFilsDroit(i) < size) {
str += "[";
str += t.get(getFilsDroit(i));
str += toString(getFilsDroit(i));
str += "]";
}
return str;
}
//insert value and sort
public void inser(int value) {
t.add(value);
int index = t.size() - 1;
if (index > 0) {
inserCheck(index); // O(log n)
}
}
public void inserCheck(int i) {
int temp = 0;
int parent = getParent(i);
if (parent >= 0 && t.get(i) > t.get(parent)) {
temp = t.get(parent);
t.set(parent, t.get(i));
t.set(i, temp);
inserCheck(parent);
}
}
//switch position of last element is list with first (deletes first and return it)
public int supprMax() {
int size = t.size();
int max = 0;
if (size > 0) {
max = t.get(0);
t.set(0, t.get(size - 1));
t.remove(size - 1);
supprMax(0);
}
else {
throw new IllegalStateException();
}
return max;
}
public void supprMax(int i) {
int size = t.size();
int temp = 0;
int index = i;
if (getFilsGauche(i) < size && t.get(getFilsGauche(i)) > t.get(index)) {
index = getFilsGauche(i);
}
if (getFilsDroit(i) < size && t.get(getFilsDroit(i)) > t.get(index)) {
index = getFilsDroit(i);
}
if (index != i) {
temp = t.get(index);
t.set(index, t.get(i));
t.set(i, temp);
supprMax(index);
}
}
public static void tri(int[] tab) {
Tas tas = new Tas();
for (int i = 0; i < tab.length; i++) {
tas.inser(tab[i]);
}
for (int i = 0; i < tab.length; i++) {
tab[i] = tas.supprMax();
}
}
}
The last 3 lines of the test are :
-2145024521
-2147061786
-2145666206
But the last 3 of my code are :
-2145024521
-2145666206
-2147061786
The problem are probably with the inser and supprMax methods.
I hate to get a bad grade just because of 3 lines placement, because it is a program that verify the code, it dosn't care the the solution was close, it's still says it's wrong.

Representing a string with more than 4 chars as 4 chars

public class CreditCardNumber {
private String issuerId;
private String accountNum;
private int checkDigit = 9;
private StringBuilder builder;
public CreditCardNumber(String id, String accNum) {
this();
if (id != null && accNum != null && id.length() == 6 && accNum.length() == 9 && isDigit(id) == true
&& isDigit(accNum) == true) {
accountNum = accNum;
issuerId = id;
}
setCheckDigit();
}
public CreditCardNumber() {
issuerId = "000000";
accountNum = "999999999";
}
public String getId() {
return issuerId;
}
public String getAccNum() {
return accountNum;
}
public int getCheckDigit() {
return checkDigit;
}
// A
private void setCheckDigit() {
int sum = checkSum();
int temp = sum + checkDigit;
if(temp%10 != 0) {
int num = temp%10;
checkDigit = checkDigit - num;
}
}
// Method to check if each character in string is a digit
public boolean isDigit(String s) {
boolean condition = true;
for (int i = 0; i < s.length(); i++) {
if (Character.isDigit(s.charAt(i))) {
condition = true;
}
}
return true;
}
// B
public void changeId(String id) {
int max = 9;
int min = 0;
if (id != null && id.length() == 6 && isDigit(id) == true) {
issuerId = id;
}
builder = new StringBuilder();
for (int i = 0; i <= 9; i++) {
int randomNum = (int) (Math.random() * (max - min + 1)) + min;
builder.append(randomNum);
accountNum = builder.toString();
}
setCheckDigit();
}
// C
private int checkSum() {
int sum = 0;
builder = new StringBuilder();
builder.append(issuerId);
builder.append(accountNum);
for (int i = 0; i < builder.length(); i++) {
// In each of the chars with an EVEN index
if (i % 2 == 0) {
int x = Integer.parseInt(Character.toString(builder.charAt(i))); //// get the int value from the char
int y = x * 2; // multiply it by 2
if (y >= 10) {
int z = y % 10;
z += 1; //// if doubling it has 2 digits, add those digits
builder.setCharAt(i, Character.forDigit(z, 10)); // put above result back into the StringBuilder at
// the same index
}
}
}
// Add the values of each digit in the StringBuilder
for (int i = 0; i < builder.length(); i++) {
sum += Integer.parseInt(Character.toString(builder.charAt(i)));
}
return sum;
}
//D
}
/* public String toString() {
a public method called toString (NO PARAMETERS) that returns (in a
return
statement) the issuerID, accountNum and checkDigit , BUT WITH A ' '
(space)
BETWEEN EVERY 4 CHARACTERS! (don't change any of the instance variables
here!)
}
}
*/
So my main issue here is, the directions say that I have to return these variables (all more than 4 digits) but with a delimiter ' ' between every 4 characters. I need some guidance into figuring out how to implement the "every 4 digits" part. Maybe using a StringBuilder? Please help.
To return a String with ' ' delimiters in between every four characters, use these methods:
// Takes a String as input and outputs a formatted String:
public String toFormattedString(String inputString){
StringBuilder returnStringBuilder = new StringBuilder();
for(int i = 0; i < inputString.length(); i++) {
returnStringBuilder.append(inputString.charAt(i));
if(i%4==3) {
returnStringBuilder.append(' ');
}
}
return new String(returnStringBuilder);
}
// Takes a int as input and outputs a formatted String:
public String toFormattedString(int inputInt){
return toFormattedString(Integer.toString(inputInt));
}
You can use these methods in your public String toString() method. I'm just not sure how you want the three Strings to be returned in one String return value. Do you want them appended to each other or returned in a different way?

To shrink a string "abbcccbfgh" by removing conescutive k characters till no removal can be done

To shrink a string "abbcccbfgh" by removing consecutive k characters till no removal can be done.
e.g. for k=3 output for the above string will be "afgh".
Please note that K and string both are dynamic i.e provided by the user.
I wrote the below program but I couldn't complete it. Please help.
public class Test {
public static void main(String[] args) {
String str = "abbcccbfgh";
int k = 3;
String result = removeConsecutive(str, k);
System.out.print("result is " + result);
}
private static String removeConsecutive(String str, int k) {
String str1 = str + "";
String res = "";
int len = str.length();
char c1 = 0, c2 = 0;
int count = 0;
for (int i = 0; i < len - 1; i++) {
c1 = str.charAt(i);
c2 = str.charAt(i + 1);
if (c1 == c2) {
count++;
} else {
res = res + String.valueOf(c1);
count = 0;
}
if (count == k-1) {
//remove String
}
}
return res;
}
I suggest to do it with regex:
int l = 0;
do {
l = str.length();
str = str.replaceAll("(.)\\1{" + n + "}", "");
} while (l != str.length());
n = k - 1
(.)\1{2} means any character followed by n same characters. \1 means the same character as in group #1
Is it okey to have recursion ?
public class Test {
public static void main(String[] args) {
String str = "abbcccbfgh";
int k = 3;
String result = removeConsecutive(str, k);
System.out.print("result is " + result);
}
private static String removeConsecutive(String str, int k) {
String ret = str;
int len = str.length();
int count = 0;
char c1 = 0 ;
char c2 = 0;
char last = 0 ;
for (int i = 0; i < ret.length()-1; i++) {
last = c1 ;
c1 = str.charAt(i);
c2 = str.charAt(i + 1);
if (c1 == c2 ) {
if( count > 0 ) {
if( last == c1 ) {
count ++ ;
}
else {
count = 0;
}
}
else {
count++;
}
} else {
count = 0;
}
if (count == k-1) {
int start = ((i+1) - k) + 1 ;
String one = str.substring(0, start) ;
String two = str.substring(start+k);
String new1 = one + two ;
//recursion
ret = removeConsecutive(new1, k) ;
count = 0;
}
}
return ret;
}
}
You can do it with a stack. For each character ch in the string, push it to the stack, if there's 3 consecutive same characters, pop them all. In the end, convert the stack to a string. You can improve the program a little by using a special stack that remembers the number of occurrences of each element.
import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;
public class Reduce implements Function<String, String> {
private final int k;
public Reduce(final int k) {
if (k <= 0) {
throw new IllegalArgumentException();
}
this.k = k;
}
#Override
public String apply(final String s) {
Stack<Character> stack = new Stack<>();
for (Character ch : s.toCharArray()) {
stack.push(ch);
if (stack.topCount() == k) {
stack.pop();
}
}
return stack.toString();
}
public static void main(String[] args) {
Reduce reduce = new Reduce(3);
System.out.println(reduce.apply("abbcccbfgh"));
}
private static class Stack<T> {
private class Node {
private T value;
private int count;
Node(T value) {
this.value = value;
this.count = 1;
}
}
private List<Node> nodes = new ArrayList<>();
public void push(T value) {
if (nodes.isEmpty() || !top().value.equals(value)) {
nodes.add(new Node(value));
} else {
top().count++;
}
}
public int topCount() {
return top().count;
}
public void pop() {
nodes.remove(nodes.size()-1);
}
private Node top() {
return nodes.get(nodes.size()-1);
}
#Override
public String toString() {
StringBuilder sb = new StringBuilder();
nodes.forEach(n->{
for (int i = 0; i < n.count; i++) {
sb.append(n.value);
}
});
return sb.toString();
}
}
}

Java code unable to find genes in a dna string

The following code is from Java mooc that is supposed to find all genes in a given file. The problem is that my getAllGenes method is not returning any genes for a given string of dna. I simply don't know what is wrong with the code.
The file I'm testing against (brca1line.fa) is located here https://github.com/polde-live/duke-java-1/tree/master/AllGenesFinder/dna
Thank you.
This is my java code.
public class AllGenesStored {
public int findStopCodon(String dnaStr,
int startIndex,
String stopCodon){
int currIndex = dnaStr.indexOf(stopCodon,startIndex+3);
while (currIndex != -1 ) {
int diff = currIndex - startIndex;
if (diff % 3 == 0) {
return currIndex;
}
else {
currIndex = dnaStr.indexOf(stopCodon, currIndex + 1);
}
}
return -1;
}
public String findGene(String dna, int where) {
int startIndex = dna.indexOf("ATG", where);
if (startIndex == -1) {
return "";
}
int taaIndex = findStopCodon(dna,startIndex,"TAA");
int tagIndex = findStopCodon(dna,startIndex,"TAG");
int tgaIndex = findStopCodon(dna,startIndex,"TGA");
int minIndex = 0;
if (taaIndex == -1 ||
(tgaIndex != -1 && tgaIndex < taaIndex)) {
minIndex = tgaIndex;
}
else {
minIndex = taaIndex;
}
if (minIndex == -1 ||
(tagIndex != -1 && tagIndex < minIndex)) {
minIndex = tagIndex;
}
if (minIndex == -1){
return "";
}
return dna.substring(startIndex,minIndex + 3);
}
public StorageResource getAllGenes(String dna) {
//create an empty StorageResource, call it geneList
StorageResource geneList = new StorageResource();
//Set startIndex to 0
int startIndex = 0;
//Repeat the following steps
while ( true ) {
//Find the next gene after startIndex
String currentGene = findGene(dna, startIndex);
//If no gene was found, leave this loop
if (currentGene.isEmpty()) {
break;
}
//Add that gene to geneList
geneList.add(currentGene);
//Set startIndex to just past the end of the gene
startIndex = dna.indexOf(currentGene, startIndex) +
currentGene.length();
}
//Your answer is geneList
return geneList;
}
public void testOn(String dna) {
System.out.println("Testing getAllGenes on " + dna);
StorageResource genes = getAllGenes(dna);
for (String g: genes.data()) {
System.out.println(g);
}
}
public void test() {
FileResource fr = new FileResource();
String dna = fr.asString();
// ATGv TAAv ATG v v TGA
//testOn("ATGATCTAATTTATGCTGCAACGGTGAAGA");
testOn(dna);
// ATGv v v v TAAv v v ATGTAA
//testOn("ATGATCATAAGAAGATAATAGAGGGCCATGTAA");
}
}
The data in the file is like "acaagtttgtacaaaaaagcagaagggccgtcaaggcccaccatgcctattggatccaaagagaggccaacatttttt". You are searching for uppercase characters in a string containing only lower case characters. String.indexOf will therefore never find TAA, TAG or TGA. Change the strings to a lower case.
int startIndex = dna.indexOf("atg", where);
...
int taaIndex = findStopCodon(dna,startIndex,"taa");
int tagIndex = findStopCodon(dna,startIndex,"tag");
int tgaIndex = findStopCodon(dna,startIndex,"tga");
Responding to the comment below: if you want to be able to handle mixed case, like you do in your text, you need to lowercase() the string first.

What is wrong with my palindrome?

Problem:
Develop a recursive algorithm to determine if there is a palindrome hidden within a longer word or phrase. A palindrome is a word or phrase that has the same sequence of letters when read from left to right and when read from right to left, ignoring the spaces (e.g., Some like cake, but I prefer pie contains the palindrome I prefer pi).
Below is my code:
public class e125 {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
int i = 0;
String sLine = "Some like cake, but I prefer pie";
sLine.replaceAll("\\s+", "");
System.out.println(PlainRet(sLine, i));
}
public static String PlainRet(String sLine, int i) {
int nNum;
char c = 0;
String sPlain = "";
if (i >= sLine.length()) {
return "No Plaindrome";
}
c = sLine.charAt(i);
nNum = Isgood(sLine, c, i);
if (nNum != 0) {
for (; i < nNum; i++) {
sPlain += sLine.charAt(i);
}
return sPlain;
}
return PlainRet(sLine, i + 1);
}
public static int Isgood(String sLine, char c, int i) {
for (int j = i + 1; j < sLine.length(); j++) {
if (Character.toUpperCase(sLine.charAt(j)) == Character.toUpperCase(c)) {
if (Isplain(sLine, i, j)) {
return j;
}
}
}
return 0;
}
public static boolean Isplain(String sLine, int i, int j) {
if (Character.toUpperCase(sLine.charAt(j)) != Character.toUpperCase(sLine.charAt(i))) {
return false;
}
else if (i == j || j == i + 1) {
return true;
}
return (Isplain(sLine, i + 1, j - 1));
}
}
I keep getting an output of "I"
I have no idea what is wrong.
Like FatalError commented sLine.replaceAll() returns a new String. You need to reassign sLine or pass the results of the replaceAll() into the method.
You'll find a new error to fix after you do that, but it's just an off-by-one!

Categories

Resources