Please find below a function in my code:
private static List<String> formCrfLinesWithMentionClass(int begin, int end, String id,
List<String> mList, int mListPos, List<String> crf) {
List<String> crfLines = crf;
int yes = 0;
mListPosChanged = mListPos;
//--------------------------------------------------------------------------
for (int crfLinesMainIter = begin; crfLinesMainIter < end; ) {
System.out.println(crfLines.get(crfLinesMainIter));
//---------------------------------------------------------------------------
//the total number of attributes without orthographic features
//in a crfLine excluding the class attribute is 98
if (!crfLines.get(crfLinesMainIter).equals("") && crfLines.get(crfLinesMainIter).split("\\s").length == 98) {
//in mList parenthesis are represented by the symbol
//in crfLines parenthesis are represented by -LRB- or -RRB-
//we make a check to ensure the equality is preserved
if(val.equals(crfLines.get(crfLinesMainIter).split("\\s")[0])) {
yes = checkForConsecutivePresence(crfLinesMainIter, mList, mListPos, id, crfLines);
if (yes > 0) {
mListPosChanged += yes;
System.out.println("formCrfLinesWithMentionClass: "+mListPosChanged);
for (int crfLinesMentionIter = crfLinesMainIter;
crfLinesMentionIter < crfLinesMainIter + yes;
crfLinesMentionIter++) {
String valString = "";
if (crfLinesMentionIter == crfLinesMainIter) {
valString += crfLines.get(crfLinesMentionIter);
valString += " B";
crfLines.add(crfLinesMentionIter, valString);
}
else {
valString += crfLines.get(crfLinesMentionIter);
valString += " I";
crfLines.add(crfLinesMentionIter, valString);
}
}
crfLinesMainIter += yes;
}
else {
++crfLinesMainIter;
}
}
else {
++crfLinesMainIter;
}
}
else {
++crfLinesMainIter;
}
}
return crfLines;
}
The problem I face is as follows:
crfLines is a List collections interface.
When the for loop (between //-----) starts out, the crfLines.get(crfLinesMainIter) works fine. But once, it enters into the if and other processing is carried out on it, even though "crfLinesMainIter" changes the crfLines.get(crfLinesMainIter) seems to get a certain previous value. It does not retrieve the actual value at the index. Has anyone faced such a scenario? Would anyone be able to tell me why this occurs?
My actual question is, when does it occur that even though the indexes might be different a list.get() function still retrieves a value from before which was at another index?
For example:
List crfLines = new LinkedList<>();
if crfLinesMainIter = 2
crfLines.get(crfLinesMainIter) brings me a value say 20 and this value 20 satisfies the if loop condition. So then further processing happens. Now when the for loop executes the values of crfLinesMainIter changes to say 5. In this case, crfLines.get(5) should actually bring me a different value, but it still brings me the previous value 20.
(Not an answer.)
Reworked (more or less) for some modicum of readability:
private static List<String> formCrfLinesWithMentionClass(int begin, int end, String id, List<String> mList, int mListPos, List<String> crf) {
List<String> crfLines = crf;
mListPosChanged = mListPos;
int i = begin;
while (i < end) {
if (crfLines.get(i).equals("") || (crfLines.get(i).split("\\s").length != 98)) {
++i;
continue;
}
if (!val.equals(crfLines.get(i).split("\\s")[0])) {
++i;
continue;
}
int yes = checkForConsecutivePresence(i, mList, mListPos, id, crfLines);
if (yes <= 0) {
++i;
continue;
}
mListPosChanged += yes;
for (int j = i; j < i + yes; j++) {
String valString = crfLines.get(j);
valString += (j == i) ? " B" : " I";
crfLines.add(j, valString);
}
i += yes;
}
return crfLines;
}
What is mListPostChanged? I find it confusing that it's being set to the value of a parameter named mListPos--it makes me think the m prefix is meaningless.
What is val in the line containing the split?
Related
In the given array in Java, [766-09-9090, 766-09-9090, 877-90-9090, 877-90-9090, "S", "T", "U"]
How could we obtain a new array with values like this :
[766-09-9090, 877-90-9090, 877-90-9090, 766-90-9090, "S", "T", "U"]
Note : No changes on non SSN values like "S", "T, "U"
This is my first stab but I am not getting the results I am looking for. Any suggestion would be appreciate
public static modifyArray(List<String> arrays) {
List<String> newArray = new ArrayList<String>();
boolean matchedFound = false;
for (int index = 0; index < arrays.size(); index++) {
if (arrays.get(index).length() == 9 && isValidSSN(arrays.get(index))) {
String nextMatchingSsn = getNextDistinctSsn(arrays);
System.out.println("Next Distinct SSN IS : " + nextMatchingSsn);
if (nextMatchingSsn != "") {
String[] pair = nextMatchingSsn.split(":");
if (pair.length == 2) {
Integer key = Integer.parseInt(pair[1]);
String ssn = pair[0];
swap(arrays.toArray(), index, key);
}
}
newArray.add(nextMatchingSsn);
} else {
System.out.println("Non Matching " + arrays.get(index));
newArray.add(arrays.get(index));
}
}
}
private static boolean isValidSSN(String s) {
if (s.length() != 9) {
throw new IllegalArgumentException("An SSN length must be 9");
}
for (int i = 0; i < 9; i++)
if (!Character.isDigit(s.charAt(i))) {
throw new IllegalArgumentException("SSN must have only digits.");
}
return (true);
}
private static String getNextDistinctSsn(List<String> ssns) {
String firstDiffSsn = "";
String currentSsn = "";
for (int index = 0; index < ssns.size(); index++) {
if (!currentSsn.equals(ssns.get(index)) && currentSsn != "") {
firstDiffSsn = ssns.get(index);
return firstDiffSsn + ":" + index;
} else {
currentSsn = ssns.get(index);
}
}
return firstDiffSsn;`enter code here`
}
public static final <T> void swap (T[] a, int i, int j) {
T t = a[i];
a[i] = a[j];
a[j] = t;
}
This is my first stab but I am not getting the results I am looking for. Any suggestion would be appreciated. So basically, if I have to write a unit test my expected result would look something like this:
public void validateResult(){
}
I can see a number of problems.
Your code is creating a new list (called newArray !?!) and populating it, but then not using it.
Your code is splitting SSNs on a : character, but the input data has no : characters.
Your SSN validation method will throw an unchecked exception if it encounters something that is not a valid SSN, but your code expects it to return false in that scenario.
This is wrong: currentSsn != "". Do not use == or != to compare strings. You are liable to get an incorrect result.
And so on.
Problem: Remove the substring t from a string s, repeatedly and print the number of steps involved to do the same.
Example: t = ab, s = aabb. In the first step, we check if t is contained within s. Here, t is contained in the middle i.e. a(ab)b. So, we will remove it and the resultant will be ab and increment the count value by 1. We again check if t is contained within s. Now, t is equal to s i.e. (ab). So, we remove that from s and increment the count. So, since t is no more contained in s, we stop and print the count value, which is 2 in this case.
I tried to solve this using recursion
static int maxMoves(String s, String t) {
if ( null == s || "" == s || null == t || "" == t){
return 0;
}
int i = s.indexOf(t);
if(i != -1) {
return maxMoves(s.substring(0, i)+ s.substring(i+t.length(), s.length()), t) + 1;
} else {
return 0;
}
}
But I am only passing 9/14 test cases. I also tried this,
static int maxMoves(String s, String t) {
int count = 0,i;
while(true)
{
if(s.contains(t))
{
i = s.indexOf(t);
s = s.substring(0,i) + s.substring(i + t.length());
}
else break;
++count;
}
return count;
}
But that also only passed 9/14 cases.
Could anyone help me figure out which cases I am not covering?
Simply you can use String::replaceFirst with a while loop for example:
String s = "aabb";
String t = "ab";
int count = 0;
while (s.contains(t)) {
s = s.replaceFirst(Pattern.quote(t), "");
count++;
}
System.out.println(count);
Use String#replace
String s = "aabb";
String oldstr = s;
String x = "ab";
while(s.contains(x)){
s = s.replace(x, "");
}
System.out.println((oldstr.length()-s.length())/x.length());
An easy and efficient way is to accumulate the string character-by-character in a StringBuilder; if at any time its buffer ends with the string you want to replace, remove it:
StringBuilder sb = new StringBuilder();
int c = 0;
for (int i = 0; i < s.length(); ++i) {
sb.append(s.charAt(i));
int last = sb.length()-t.length();
if (last >= 0 && sb.indexOf(t, last) == last) {
sb.setLength(last);
++c;
}
}
// c is now the number of times you removed t from s.
I'm working on a project where I want to be able to be able to parse some text and find nouns and a lot of the text I want to parse has pronouns in it for Example => "Emma the parrot was a bird. She lived in a tall tree".
I don't want to work with "She's" etc. as they aren't seen as nouns in the dictionary I'm working with so I've been working on a method to replace She etc with the previous occurrence of a name. So the above example would output to => "Emma the parrot was a bird. Emma lived in a tall tree".
The method is working fine when I have a small sample however when I'm working with 3-4 different people in one text it doesn't work.
public static String replacePronouns(String text, ArrayList<String> dictionary) {
String[] strArray = text.replaceAll("\\.", " .").replaceAll("\\,", "").split("\\s+");
String previousName = "";
for(int i = 0; i < strArray.length; i++ ) {
//we'll have to set this to be more dynamic -> change to pronouns in dicitonary
if(strArray[i].equals("His") || strArray[i].equals("She") || strArray[i].equals("she") || strArray[i].equals("him") || strArray[i].equals("he") || strArray[i].equals("her")) {
for(int j = (i-1); j>=0; j--) {
int count = dictionary.size()-1;
boolean flag = false;
while(count>=0 && flag==false) {
if(strArray[j].equals(dictionary.get(count).split(": ")[1]) && dictionary.get(count).split(": ")[0].equals("Name")) {
previousName = strArray[j];
flag = true; }
count--;
} }
strArray[i] = previousName; } }
return Arrays.toString(strArray).replaceAll("\\[", "").replaceAll("\\,", "").replaceAll("\\]", "");
}
It takes in my text
String text = "Karla was a bird and she had beautifully colorful feathers. She lived in a tall tree.
And a "dictionary"
ArrayList<String> dictionary = new ArrayList<>();
dictionary.add("Name: hunter");
dictionary.add("Name: Karla");
dictionary.add("Noun: hawk");
dictionary.add("Noun: feathers");
dictionary.add("Noun: tree");
dictionary.add("Noun: arrows");
dictionary.add("Verb: was a");
dictionary.add("Verb: had");
dictionary.add("Verb: missed");
dictionary.add("Verb: knew");
dictionary.add("Verb: offered");
dictionary.add("Verb: pledged");
dictionary.add("Verb: shoot");
But it always outputs Karla in this example, even if we had "The hunter shot his gun" in the same string.
Any help on why this isn't working would be appreciated
This isn't working because you continue looping over j even after you've found a match in the dictionary. That is - you keep looking back towards the beginning of the string, and eventually find "Karla", even though you've already matched "hunter".
There are many ways you could fix this. One very simple one would be to move boolean flag = false; up to before the for loop over j, and change the condition from j >= 0 to j >= 0 && !flag, so that you stop looping as soon as flag is true. Like so :
public static String replacePronouns(String text, ArrayList<String> dictionary) {
String[] strArray = text.replaceAll("\\.", " .").replaceAll("\\,", "").split("\\s+");
String previousName = "";
for (int i = 0; i < strArray.length; i++) {
boolean flag = false;
// we'll have to set this to be more dynamic -> change to pronouns in dicitonary
if (strArray[i].equals("His") || strArray[i].equals("She") || strArray[i].equals("she") || strArray[i].equals("him") || strArray[i].equals("he") || strArray[i].equals("her")) {
for (int j = (i - 1); j >= 0 && flag == false; j--) {
int count = dictionary.size() - 1;
while (count >= 0) {
if (strArray[j].equals(dictionary.get(count).split(": ")[1]) && dictionary.get(count).split(": ")[0].equals("Name")) {
previousName = strArray[j];
flag = true;
}
count--;
}
}
strArray[i] = previousName;
}
}
return Arrays.toString(strArray).replaceAll("\\[", "").replaceAll("\\,", "").replaceAll("\\]", "");
}
If you placed your } characters in a more standard way, this kind of error would be easier to see.
I have a method that is supposed to return the smallest value of an array. The array is in the parametre of the method, so you input the values of your own choosing when you make an object of the class. This is the method I have come up with so far:
public class minsteNummer {
public minsteNummer() {
}
public int minsteNummer(Integer[] nummer) {
int minste = 0;
for(int i = 0; i< nummer.length; i++){
if(nummer[i] <= nummer.length) {
minste = i;
System.out.println("Minste nummer er " + minste);
} else if(nummer.length == 0) {
return 0;
}
}
return 0;
}
}
It does not execute the way I want it to, and I cant figure out what exacly it prints, but it is definetly not the smalles number of the array. I have tried with a while loop, but that does not work either.
Does anyone know where the fault in the code is, and how to improve it? I would also like it to just return, not print, the smalles number, but when I try to put "return minste;" in the if-statement, it says "unexpected return value".
Thanks in advance.
There are few places in your code that need attention:
As method scope is public you should always check for invalid input
Should not assign: int minste = 0; as there could be a negative number in a given array
When assign minimum number, should always compare it to the loop current number
if (minste > nummer[i]) minste = nummer[i];
Finally always return your minimum number return minste;
All together:
public static int minsteNummer(Integer[] nummer) {
if (nummer==null || nummer.length == 0) {
throw new IllegalArgumentException("Bad or empty array");
}
int minste = nummer[0];
for (int i = 1; i< nummer.length; i++){
if (minste > nummer[i]) minste = nummer[i];
}
System.out.println("Minste nummer er " + minste);
return minste;
}
It is worth to mention that you could use Java build-in functionality for such a basic task, i.e. sort array in ascending order and get first element:
public static int minsteNummer(Integer[] nummer) {
if (nummer==null || nummer.length == 0) {
throw new IllegalArgumentException("Bad or empty array");
}
Arrays.sort(nummer);
return nummer[0];
}
use streams
Integer[] arrayB = null;
OptionalInt min = Arrays.stream(arrayB).mapToInt(Integer::intValue).min();
public int minsteNummer(Integer[] nummer) {
int minste = Integer.MAX_VALUE;
for(int i = 0; i< nummer.length; i++){
if(nummer[i] < minste ) {
minste = nummer[i] ;
}
if(minste != Integer.MAX_VALUE)
return minste;
else
return 0;
}
I'm writing a calculator code that solves the input whats given in string. All is good, except when it gets a negative result in the parentheses it fails badly because two operations get next to each other:
1+2*(10-11) >> 1+2*(-1) >> 1+2*-1
So where *- is, it gets "" (nothing) in the BigDecimal's constructor.
I know what's the problem, but how can I solve it?
import java.math.BigDecimal;
import java.util.ArrayList;
public class DoMath {
public static void main(String[] args) {
// Test equation goes here.
String number = "95.3+43.23*(10-11.1)";
System.out.println(doMath(number));
}
public static BigDecimal doMath(String input) {
StringBuilder builtInput = new StringBuilder(input);
StringBuilder help = new StringBuilder();
// Check if there are parenthesis in the equation.
boolean noParenthesis = true;
for (int i = 0; i < builtInput.length(); i++) {
if (builtInput.charAt(i) == 40) {
noParenthesis = false;
break;
}
}
if (noParenthesis) { // If there are no parenthesis, calculate the equation!
return calculateAndConvert(builtInput);
} else { // If there are parenthesis, breakdown to simple equations!
int parenthesePair = 0;
// Start extracting characters from the builtInput variable.
for (int i = 0; i < builtInput.length(); i++) {
// Start where we find a parentheses opener.
if (builtInput.charAt(i) == 40) {
parenthesePair = 1;
builtInput.deleteCharAt(i);
for (int j = i; j < builtInput.length(); j++) {
// If we find another opener, add one to parenthesePair variable.
if (builtInput.charAt(j) == 40) {
parenthesePair++;
}
// If we find a closer, subtract one from the given variable.
if (builtInput.charAt(j) == 41) {
parenthesePair--;
}
// If we have found the matching pair, delete it and break the for loop.
if (parenthesePair == 0) {
builtInput.deleteCharAt(j);
builtInput.insert(j, doMath(help.toString()));
break;
}
help.append(builtInput.charAt(j));
builtInput.deleteCharAt(j);
j--;
}
break;
}
}
}
System.out.println(builtInput);
return doMath(builtInput.toString());
}
public static BigDecimal calculateAndConvert(StringBuilder input) {
ArrayList<BigDecimal> listOfNumbers = new ArrayList<BigDecimal>();
StringBuilder numBay = new StringBuilder();
StringBuilder operations = new StringBuilder();
// If the first character is -, the first number is negative.
boolean firstIsNegative = false;
if (input.charAt(0) == 45) {
firstIsNegative = true;
input.deleteCharAt(0);
}
// Converting to numbers.
while (input.length() != 0) {
// If the character is a number or a dot, put it in the numBay variable and delete the char.
if (input.charAt(0) >= 48 && input.charAt(0) <= 57 || input.charAt(0) == 46) {
numBay.append(input.charAt(0));
// If the character is not a number, put it in the operations variable
// and save the number in the list (not operator characters are filtered)
} else {
listOfNumbers.add(new BigDecimal(numBay.toString()));
numBay.setLength(0);
operations.append(input.charAt(0));
}
// Delete the character.
input.deleteCharAt(0);
}
listOfNumbers.add(new BigDecimal(numBay.toString()));
// Setting first number to negative if it's needed.
if (firstIsNegative) {
listOfNumbers.set(0, listOfNumbers.get(0).negate());
}
// Calculate the result from the list and operations and return it.
return calculate(listOfNumbers, operations);
}
public static BigDecimal calculate(ArrayList<BigDecimal> list, StringBuilder ops) {
BigDecimal momentaryResult;
// Check for a multiply operation - if there is one, solve it.
for (int i = 0; i < ops.length(); i++) {
if (ops.charAt(i) == 42) {
momentaryResult = list.get(i).multiply(list.get(i + 1));
list.remove(i);
list.set(i, momentaryResult);
ops.deleteCharAt(i);
i--;
}
}
// Check for a divide operation - if there is one, solve it.
for (int i = 0; i < ops.length(); i++) {
if (ops.charAt(i) == 47) {
momentaryResult = list.get(i).divide(list.get(i + 1));
list.remove(i);
list.set(i, momentaryResult);
ops.deleteCharAt(i);
i--;
}
}
// Check for a subtract operation - if there is one, solve it.
for (int i = 0; i < ops.length(); i++) {
if (ops.charAt(i) == 45) {
momentaryResult = list.get(i).subtract(list.get(i + 1));
list.remove(i);
list.set(i, momentaryResult);
ops.deleteCharAt(i);
i--;
}
}
// Check for a plus operation - if there is one, solve it.
for (int i = 0; i < ops.length(); i++) {
if (ops.charAt(i) == 43) {
momentaryResult = list.get(i).add(list.get(i + 1));
list.remove(i);
list.set(i, momentaryResult);
ops.deleteCharAt(i);
i--;
}
}
// Return with the one remaining number that represents the result.
return list.get(0);
}
}
Edit: or would it be easier to write a new code with a different algorithm...?
I would post this as a comment to your question, but I do not have the required reputation to do so.
Anyway, since you have already recognized that the bug is the "operator" *- couldn't you make a method that would fix this problem by replacing the plus operator immediately before by a minus? Like this:
1+2*-1 >>> 1-2*1
If you want I can write you the code. But maybe it will be easier for you to adapt a solution like this in your code that is already working.
Edit - 1:
Obviously, the code should also treat the following cases:
1-2*-1 >>> 1+2*1
2*-1 >>> -2*1
Edit - 2:
Here is the code I managed to make. Let me know if you find any errors.
public int countChar(String str, char chr) {
int count = 0;
for (int k = 0; k < str.length(); k++) {
if (str.charAt(k) == chr)
count++;
}
return count;
}
public String fixBug(String eq) {
boolean hasBug = eq.contains("*-");
if (hasBug) {
String subeq;
int indbug, indp, indm;
eq = eq.replace("*-", "#");
int N = countChar(eq, '#');
for (int k = N; k > 0; k--) {
indbug = eq.indexOf('#');
subeq = eq.substring(0, indbug);
indp = subeq.lastIndexOf('+');
indm = subeq.lastIndexOf('-');
if (indp == -1 && indm == -1) {
eq = "-" + eq;
} else if (indp > indm) {
eq = eq.substring(0, indp) + '-' + eq.substring(indp + 1);
} else {
eq = eq.substring(0, indm) + '+' + eq.substring(indm + 1);
}
}
eq = eq.replace("#", "*");
}
return eq;
}