Java: find sub sequences - java

Required to find the first occurrence in this sequence and return position of this occurrence.
I find LazySeq lib in github.

Seems to work:
// The concept of an infinite sequence is that there is always a next.
abstract static class InfiniteIterator<T> implements Iterator<T> {
#Override
public boolean hasNext() {
return true;
}
}
// The digits of all decimal numbers concatenated.
static class InfiniteDigits extends InfiniteIterator<Character> {
// The number we are working on.
int n = 1;
// The String version of n
String s = Integer.toString(n);
// Where we are in the string.
int i = 0;
#Override
public Character next() {
if (i >= s.length()) {
s = Integer.toString(++n);
i = 0;
}
return s.charAt(i++);
}
}
// Finds a String in a stream of characters.
static class StringFinder {
// The source of the stream.
final Iterator<Character> source;
// Track of the past.
final StringBuilder traversed = new StringBuilder();
public StringFinder(Iterator<Character> source) {
this.source = source;
}
public int find(final String find) {
// How far we've matched.
int matched = 0;
// How many characters we've passed.
int passed = 0;
// Walk the source until we get a match.
while (matched < find.length()) {
Character next = source.next();
traversed.append(next);
if (next == find.charAt(matched)) {
// Still matching!
matched += 1;
} else {
// Mismatch.
passed += matched + 1;
matched = 0;
}
}
// Want 1-based position.
return passed + 1;
}
}
private void test(String string) {
StringFinder finder = new StringFinder(new InfiniteDigits());
System.out.println("'" + string + "' found at " + finder.find(string) + " traversed " + finder.traversed);
}
public void test() {
test("567");
test("1112");
test("765");
}
NB: The traversed field is there for debugging. I would suggest you remove it before you test in anger.
Prints:
'567' found at 5 traversed 1234567
'1112' found at 12 traversed 123456789101112
'765' found at 1619 traversed 1234567891011121314...85695705715725735745755765

Related

how to count many times a character occurs in a string without using s loop

the code below is meant to count each time character 'x' occurs in a string but it only counts once ..
I do not want to use a loop.
public class recursionJava
{
public static void main(String args[])
{
String names = "xxhixx";
int result = number(names);
System.out.println("number of x: " + result);
}
public static int number (String name)
{
int index = 0, result = 0;
if(name.charAt(index) == 'x')
{
result++;
}
else
{
result = result;
}
index++;
if (name.trim().length() != 0)
{
number(name);
}
return result;
}
}
You could do a replacement/removal of the character and then compare the length of the resulting string:
String names = "xxhixx";
int numX = names.length() - names.replace("x", "").length(); // numX == 4
If you don't want to use a loop, you can use recursion:
public static int number (String name)
{
if (name.length () == 0)
return 0;
int count = name.charAt(0)=='x' ? 1 : 0;
return count + number(name.substring(1));
}
As of Java 8 you can use streams:
"xxhixx".chars().filter(c -> ((char)c)=='x').count()
Previous recursive answer (from Eran) is correct, although it has quadratic complexity in new java versions (substring copies string internally). It can be linear one:
public static int number(String names, int position) {
if (position >= names.length()) {
return 0;
}
int count = number(names, position + 1);
if ('x' == names.charAt(position)) {
count++;
}
return count;
}
Your code does not work because of two things:
Every time you're calling your recursive method number(), you're setting your variables index and result back to zero. So, the program will always be stuck on the first letter and also reset the record of the number of x's it has found so far.
Also, name.trim() is pretty much useless here, because this method only removes whitespace characters such as space, tab etc.
You can solve both of these problems by
making index and result global variables and
using index to check whether or not you have reached the end of the String.
So in the end, a slightly modified (and working) Version of your code would look like this:
public class recursionJava {
private static int index = 0;
private static int result = 0;
public static void main(String[] args) {
String names = "xxhixx";
int result = number(names);
System.out.println("number of x: " + result);
}
public static int number (String name){
if(name.charAt(index) == 'x')
result++;
index++;
if(name.length() - index > 0)
number(name);
return result;
}
}
You can use StringUtils.countMatches
StringUtils.countMatches(name, "x");

How to convert an Array method to an ArrayList method?

How can I alter the below method to work with an ArrayList?
I was thinking something like this:
public static boolean sortArrayList(ArrayList<Integer> list) {
return false;
}
but i'm not sure how to complete it.
Here is the method that I am trying to convert from working with an Array to instead work with an ArrayList:
public static boolean sortArrayList(final int[] data) {
for(int i = 1; i < data.length; i++) {
if(data[i-1] > data[i]) {
return false;
}
}
return true;
}
public static boolean sortArrayList(final ArrayList <Integer> data) {
for (int i = 1; i < data.size(); i++) {
if (data.get(i - 1) > data.get(i)) {
return false;
}
}
return true;
}
I have a few problems with the accepted answer, as given by #Sanj: (A) it doesn't handle nulls within the list, (B) it is unnecessarily specialized to ArrayList<Integer> when it could easily be merely Iterable<Integer>, and (C) the method name is misleading.
NOTE: For (A), it's quite possible that getting an NPE is appropriate - the OP didn't say. For the demo code, I assume that nulls are ignorable. Other interpretations a also fair, e.g. null is always a "least" value (requiring different coding, LAAEFTR). Regardless, the behaviour should be JavaDoc'ed - which I didn't do in my demo #8>P
NOTE: For (B), keeping the specialized version might improve runtime performance, since the method "knows" that the backing data is in an array and the compiler might extract some runtime efficiency over the version using an Iterable but such claim seem dubious to me and, in any event, I would want to see benchmark results to support such. ALSO Even the version I demo could be further abstracted using a generic element type (vs limited to Integer). Such a method might have definition like:
public static <T extends Comparable<T>> boolean isAscendingOrder(final Iterable<T> sequence)
NOTE: For (C), I follow #Valentine's method naming advice (almost). I like the idea so much, I took it one step further to explicitly call out the directionality of the checked-for-sortedness.
Below is a demonstration class that shows good behaviour for a isAscendingOrder which address all those issues, followed by similar behaviour by #Sanj's solution (until the NPE). When I run it, I get console output:
true, true, true, true, false, true
------------------------------------
true, true, true, true, false,
Exception in thread "main" java.lang.NullPointerException
at SortCheck.sortArrayList(SortCheck.java:35)
at SortCheck.main(SortCheck.java:78)
.
import java.util.ArrayList;
public class SortCheck
{
public static boolean isAscendingOrder(final Iterable<Integer> sequence)
{
Integer prev = null;
for (final Integer scan : sequence)
{
if (prev == null)
{
prev = scan;
}
else
{
if (scan != null)
{
if (prev.compareTo(scan) > 0)
{
return false;
}
prev = scan;
}
}
}
return true;
}
public static boolean sortArrayList(final ArrayList<Integer> data)
{
for (int i = 1; i < data.size(); i++)
{
if (data.get(i - 1) > data.get(i))
{
return false;
}
}
return true;
}
private static ArrayList<Integer> createArrayList(final Integer... vals)
{
final ArrayList<Integer> rval = new ArrayList<>();
for(final Integer x : vals)
{
rval.add(x);
}
return rval;
}
public static void main(final String[] args)
{
final ArrayList<Integer> listEmpty = createArrayList();
final ArrayList<Integer> listSingleton = createArrayList(2);
final ArrayList<Integer> listAscending = createArrayList(2, 5, 8, 10 );
final ArrayList<Integer> listPlatuea = createArrayList(2, 5, 5, 10 );
final ArrayList<Integer> listMixedUp = createArrayList(2, 5, 3, 10 );
final ArrayList<Integer> listWithNull = createArrayList(2, 5, 8, null);
System.out.print(isAscendingOrder(listEmpty ) + ", ");
System.out.print(isAscendingOrder(listSingleton) + ", ");
System.out.print(isAscendingOrder(listAscending) + ", ");
System.out.print(isAscendingOrder(listPlatuea ) + ", ");
System.out.print(isAscendingOrder(listMixedUp ) + ", ");
System.out.print(isAscendingOrder(listWithNull ) + "\n");
System.out.println("------------------------------------");
System.out.print(sortArrayList(listEmpty ) + ", ");
System.out.print(sortArrayList(listSingleton) + ", ");
System.out.print(sortArrayList(listAscending) + ", ");
System.out.print(sortArrayList(listPlatuea ) + ", ");
System.out.print(sortArrayList(listMixedUp ) + ", ");
System.out.print(sortArrayList(listWithNull ) + "\n");
}
}
Try below function, it takes integer array and converts it into a ArrayList and then computes the result :
public static boolean sortArrayList(final int[] data) {
List<Integer> aList = new ArrayList<Integer>();
for (int index = 0; index < data.length; index++)
aList.add(data[index]);
for (int i = 1; i < aList.size(); i++) {
if (aList.get(i - 1) > aList.get(i)) {
return false;
}
}
return true;
}

Sequential search does not work as expected

I have written a program which takes the words the user have entered, with a button press, and puts them in an ArrayList. There is also another text field where the user can enter a letter or word, for which the user can search for in the ArrayList with another button press. I'm using a sequential search algorithm to accomplish this, but it does not work as I expect it to; If the searched word is found, the search function should return, and print out in a textArea that the word was found and where in the array it was found. This works, but only for the first search. If the word is not found, the function should print out that the word was not found. This works as I want it to.
The problem is that after I searched for one word, and it displays where in the ArrayList this can be found, nothing happens when I press the button after that, whether the entered letter/word is in the array or not. It's like the string that the text gets stored isn't changing. I don't understand why... Here below is the custom Class of the search function and then my Main class:
public class Search {
static private int i;
static String index;
static boolean found = false;
public static String sequencial (ArrayList<String> list, String user) {
for (int i = 0; i < list.size(); i++) {
if (list.get(i).equals(user)) {
index = "The word " + user + " exist on the place " + i + " in the Arraylist";
found = true;
}
}
if (!found) {
index = "The word " + user + " could not be found";
}
return index;
}
My Main class:
ArrayList<String> list = new ArrayList<String>();
ArrayList<String> s = new ArrayList<String>();
private void btnAddActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
txtaOutput.setText("");
String word = txtfAdd.getText();
list.add(word);
for (int i = 0; i < list.size(); i++) {
txtaOutput.append("" + list.get(i) + "\n");
}
}
private void btnSearchActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
String user = txtfSearch.getText();
txtaOutput.setText("");
String index = Search.sequencial(list, user);
txtaOutput.setText("" + index);
}
Any help is appreciated!
The problem is that you declared your found variable as static. When your first word is found, it is set to true, and nothing ever sets it back to false. Instead of making it a static variable, declare it as a local variable inside your sequencial (it's spelled sequential, by the way) function, just before the for-loop.
In fact, all the variables you've declared as static should be made local. Declaring static variables is never a good idea.
As said by other users:
There is the List#indexOf(Object) method. You should use that instead of reinventing the wheel (unless you need to, and in that case you might have a look at the ArrayList implementation). There are also other collections, like HashSet which are more apropiate for looking up, but i guess that is another history.
The scope and the names of the variables (i, index, found) is error-prone. Do other methods or even classes need to have access to those variables? If you need to keep those variables, you might want to choose a visibility (public,protected,private). "index" is a misleading choice of a name for a message.
This would be an slightly simplified/corrected version of your code:
// Ommit those unneeded static variables
public static String sequencial (ArrayList<String> list, String user) {
int indexFound = list.indexOf(user);
if (user >= 0) {
return "The word " + user + " exist on the place " + indexFound + " in the Arraylist";
} else {
return "The word " + user + " could not be found";
}
}
...
private void btnSearchActionPerformed(java.awt.event.ActionEvent evt) {
String user = txtfSearch.getText();
// txtaOutput.setText("");
String seqMessage = sequencial(list, user);
txtaOutput.setText(seqMessage);
}
We use the static properties when you would like to use the constants. You should not use the static properties here. The problem will happen when your found property is changed the first time, it will not be changed again. And from that time, it will always be true. Similar with index property. Here is the code you can fix this:
public class Search {
public static SearchResult sequencial (ArrayList<String> list, String user) {
SearchResult result = null;
for (int i = 0; i < list.size(); i++) {
if (list.get(i).equals(user)) {
String index = "The word " + user + " exist on the place " + i + " in the Arraylist";
boolean found = true;
result = new SearchResult(index, found);
break;
}
}
if (result == null) {
String index = "The word " + user + " could not be found";
result = new SearchResult(index);
}
return result;
}
//sample inner class
static class SearchResult {
private String index;
private boolean found;
public SearchResult(String index) {
this.index = index;
}
public SearchResult(String index, boolean found) {
this.index = index;
this.found = found;
}
public String getIndex() {
return index;
}
public void setIndex(String index) {
this.index = index;
}
public boolean isFound() {
return found;
}
public void setFound(boolean found) {
this.found = found;
}
}
}
public class SequencialSearcher {
public static int SequencialSearchInt(int[] inputArray, int key)
{
for(int i=0; i < inputArray.length ; i++)
{
if(inputArray[i] == key)
{
return i;
}
}
return -1;
}
public static int SequencialSearchString(String[] array, String key)
{
for(int i=0; i < array.length ; i++)
{
if(array[i] == key)
{
return i;
}
}
return -1;
}
public static int SequencialSearchFloat(double[] array, double key)
{
for(int i=0; i < array.length ; i++)
{
if(array[i] == key)
{
return i;
}
}
return -1;
}
public static void main (String args[])
{
//select the type of the elements of search
//1 if integers
//2 if float
//3 if string
int x = 3;
int[] array1 = {9, 0, 10, 8, 5, 4, 6, 2, 3};
double[] array2 = {9.0, 0.0, 10.0, 8.0, 5.0, 4.0, 6.0, 2.0, 3.0};
String[] array3 = {"aa","hey", "hello"};
if(x == 1){
//enter the integer you want to search for here below
int requiredValue = 5;
int result = SequencialSearchInt(array1, requiredValue);
if (result != -1)
{
System.out.println("Required Value: "+requiredValue+" found at index: "+result);
}
else
{
System.out.println("Value:"+requiredValue+" not found");
}
}
else if(x == 2)
{
//enter the double you want to search for here below
double requiredValue1 = 5.0;
int result = SequencialSearchFloat(array2, requiredValue1);
if (result != -1)
{
System.out.println("Required Value: "+requiredValue1+" found at index: "+result);
}
else
{
System.out.println("Value:"+requiredValue1+" not found");
}
}
else if(x == 3){
//enter the string you want to search for here below
String requiredValue2 = "hey";
int result = SequencialSearchString(array3, requiredValue2);
if (result != -1)
{
System.out.println("Required Value: "+requiredValue2+" found at index: "+result);
}
else
{
System.out.println("Value:"+requiredValue2+" not found");
}
}
else{
System.out.println("Error. Please select 1,2 and 3 only");
}
}
}

Referring to an array in a subclass

So im writing a program to add and subtract Polynomials. The Polynomial is comes in as a String (example: 4x^7-2x^5+3x^2+78) and its split up into Terms (example 4x^7) and then the coefficient value is assigned to PolynomialArray[exponent].
This is part one of my assignment so I have an Interface that was given to me below:
public interface PolynomialInterface {
PolynomialInterface add(PolynomialInterface other);
// Effect: Adds value to owner of addPolynomial method.
// Postcondition: Return value = this + value.
PolynomialInterface subtract(PolynomialInterface other);
// Effect: Subtracts value from owner of addPolynomial method.
// Postcondition: Return value = this - value.
void readPolynomial();
// Postcondition: polynomial read.
String toString();
// Postcondition: polynomial converted to string.
}
Heres my code so far:
import java.lang.*;
public class ArrayWithExponentAsIndexPolynomial implements PolynomialInterface {
Integer PolynomialArray[] = new Integer[1000];
CharSequence minus = "-";
CharSequence plusMinus = "+-";
boolean FirstElementPos = true;
public ArrayWithExponentAsIndexPolynomial(String input) {
if (input.charAt(0) == '-') {
input = input.substring(1);
FirstElementPos = false;
}
String inputPolynomial = input.replaceAll("-", "+-");
// input.replace(minus, plusMinus);
System.out.println(inputPolynomial);
String[] splitTerms = inputPolynomial.split("\\+");
// int PolynomialArray[] = new int[100];
for (int i = 0; i <= splitTerms.length - 1; i++) {
System.out.println(splitTerms[i]);
}
String tempTemp = splitTerms[1];
int coef;
int exponent;
String tempExp = null;
for (int i = 0; i < splitTerms.length; i++) {
String tempTerm = splitTerms[i];
System.out.println();
System.out.println("Term we are working with " + tempTerm);
boolean tempPos = true;
if (tempTerm.contains("-")) {
tempTerm = tempTerm.substring(1);
System.out.println("After removing negative from term: "
+ tempTerm);
tempPos = false;
}
int IndexOfexponent = tempTerm.indexOf('^');
if (IndexOfexponent == -1) {
exponent = 1;
// FirstElementPos = true;
} else {
tempExp = tempTerm.substring(IndexOfexponent + 1);
exponent = Integer.parseInt(tempExp);
}
System.out.println("The exp is " + exponent);
// String tempTerm = splitTerms[i];
System.out.println("The term rn is: " + tempTerm);
String tempTermNoCarrot = tempTerm.replaceAll("\\^" + tempExp, "");
String tempCoef = tempTermNoCarrot.replaceAll("x", "");
// String tempCoef = tempTermNoX.replaceAll(tempExp, "");
System.out.println("THe Coeff rn is: " + tempCoef);
coef = Integer.parseInt(tempCoef);
if (tempPos == false || FirstElementPos == false) {
coef = (coef * -1);
}
System.out.println("After everything, Coef is:" + coef
+ " and exp is: " + exponent);
PolynomialArray[exponent] = coef;
}
}
public PolynomialInterface add(PolynomialInterface other) {
String finalOutput=null;
//Integer top = this.PolynomialArray[i];
Integer Sum[] = new Integer[100];
for (int i = 99; i >= 1; i--){
Integer top = this.PolynomialArray[i];
Integer bottom = other.PolynomialArray[i];
Sum[i] = top + bottom;
}
String tempOutput = null;
for (int i = 99; i >= 1; i--) {
if (Sum[i] != null && Sum[i] != 0) {
tempOutput += "+";
int outputCoef = Sum[i];
tempOutput += outputCoef;
tempOutput += "x^";
tempOutput += i;
}
}
String RemoveNull = tempOutput;
tempOutput = RemoveNull.replaceAll("null", "");
if (tempOutput.charAt(0) == '+') {
tempOutput = tempOutput.substring(1);
}
tempOutput = tempOutput.replaceAll("\\+-","-");
finalOutput = tempOutput;
return new ArrayWithExponentAsIndexPolynomial(finalOutput);
}
public PolynomialInterface subtract(PolynomialInterface other) {
return other;
}
public void readPolynomial() {
}
public String toString() {
String output = null;
for (int i = 99; i >= 1; i--) {
if (PolynomialArray[i] != null && PolynomialArray[i] != 0) {
output += "+";
int outputCoef = PolynomialArray[i];
output += outputCoef;
output += "x^";
output += i;
}
}
String outputTemp = output;
output = outputTemp.replaceAll("null", "");
if (output.charAt(0) == '+') {
output = output.substring(1);
}
output = output.replaceAll("\\+-","-");
return output;
}
}
My question is in the add mehthod, how do i refer to the PolynomialArray in the "other" object. When i do other.PolynomialArray[i] it says PolynomialArray cannot be resolved or is not a field sense in the Interface, there exists no such thing. Id there a way to refer to my intended target without changing the interface because in my future project I will need to use this
Sorry if I'm not being clear. This is my first time posting :)
*quick edit. I'm not done with my code so there are a few place holders here and there and some random print statements
Integer PolynomialArray[] = new Integer[1000];
This is something which your implementing Class ArrayWithExponentAsIndexPolynomial has added. It's not specified in your interface contract. You are trying to get the PolynomialArray[] from your interface reference. That won't work. You need to cast it like ((ArrayWithExponentAsIndexPolynomial)other).PolynomialArray[i];
Simply put, the PolynomialArray field is defined in your ArrayWithExponentAsIndexPolynomial class and unknown to the given PolynomialInterface inferface. In practice, only methods are defined in an interface, not fields (as Amit.rk3 mentioned, static final fields are allowed, though no solution to your problem). A way to access a field of an object indentified solely by an interface, is to define a getSomeField() method in the interface.
I'm not sure if your assignment allows you to add getPolynomialArray() to the given interface, but that would be the simplest solution.
Otherwise, though less elegant, you can cast the given object to your class and access the field directly.

How to fix a Null Pointer Exception upon string retrieval - hash table

class Item
{
private int address;
private String itemString;
public Item(String item)
{
separate(item);
}
public void separate(String string)
{
StringTokenizer st = new StringTokenizer(string);
itemString = st.nextToken();
if(st.hasMoreTokens())
{
address = Integer.parseInt(st.nextToken());
}
else
{
address = -1;
}
}
public String getKey()
{
return itemString;
}
public int getAddress()
{
return address;
}
public void illegitimize()
{
itemString = "*del";
address = -1;
}
}
class HashTable
{
private Item[] hashArray;
private int arraySize;
public HashTable(int size)
{
arraySize = size;
hashArray = new Item[arraySize];
}
public int hash(Item item)
{
String key = item.getKey();
int hashVal = 0;
for(int i=0; i<key.length(); i++)
{
int letter = key.charAt(i) - 96;
hashVal = (hashVal * 26 + letter) % arraySize;
}
return hashVal;
}
public void insert(Item item)
{
int hashVal = hash(item);
while(hashArray[hashVal] != null &&
!(hashArray[hashVal].getKey().contains("*")))
{
hashVal++;
hashVal %= arraySize;
}
String keyAtHashVal = hashArray[hashVal].getKey();
String itemKey = item.getKey();
if(!keyAtHashVal.equals(itemKey))
{
hashArray[hashVal] = item;
System.out.println(item.getKey() + " inserted into the table at "
+ "position " + hashVal);
}
else
{
System.out.println("Error: " + item.getKey() + " already exists "
+ "at location " + hashVal);
}
}
public Item find(Item item)
{
int hashVal = hash(item);
while(hashArray[hashVal] != null)
{
if(hashArray[hashVal].getKey().equals(item.getKey()))
{
System.out.println(item.getKey() + " found at location "
+ hashVal + " with address " + item.getAddress());
return hashArray[hashVal];
}
hashVal++;
hashVal %= arraySize;
}
System.out.println("Error: " + item.getKey() + " not found in the "
+ "table");
return null;
}
}
public class HashTableMain
{
public static void main(String[] args) throws Exception
{
File file = new File(args[0]);
Scanner input = new Scanner(file);
Item currentItem;
String currentItemsKey;
int currentItemsAddress;
HashTable table = new HashTable(50);
while(input.hasNextLine())
{
currentItem = new Item(input.nextLine());
currentItemsKey = currentItem.getKey();
currentItemsAddress = currentItem.getAddress();
if(currentItemsAddress > 0)
{
table.insert(currentItem);
}
else
{
table.find(currentItem);
}
}
}
}
The title pretty much explains it. I get a null pointer when the insert() method attempts to retrieve the key of the first item I feed it from the file. I figure this has something to do with the way I retrieve store the string but I cannot identify the problem.
The records inside the file will be in this format:
george
stacy 112
patrick 234
angelo 455
money 556
kim
chloe 223
If there is a number in the line I need to hash the item into the array at the appropriate location. If there is no number I need to search for the key (the string at the beginning of each line).
Edit: added find function. I left out anything I didn't think you needed to help me. If you need anything else let me know.
The problem seems to be at
String keyAtHashVal = hashArray[hashVal].getKey();
in the HashTable.insert() . Your hashArray[hashVal] may not have an object in it leading to a null pointer. You could do a null check.
Item existingItem = hashArray[hashVal];
if(existingItem==null) {
//do appropriate code
} else {
//do your stuff
}
BTW, StringTokenizer is deprecated and is only there for compatibility purposes. You could use the String.split() method.
Plus instead of HashTable , you can use the HashMap if you are not aware of it
String keyAtHashVal = hashArray[hashVal].getKey();
The problem is is that hashArray[hashVal] is always going to be null because you probe for a null space in a previous statement. I suspect that it should be moved inside the while() loop and used there.

Categories

Resources