There's three pieces of the code I was given in my BigInteger homework that requires us to store, as the name suggests, integers of extreme size into linked lists, given a String input.
If given a string "0054321" the resulting linked list will store 1->2->3->4->5 in positional order, disregarding insignificant digits.
But as I try to traverse through the string, I am trying to increment numDigits by 1 each time I find a significant digit.
BigInteger.java (The code I'm working on right now)
package bigint;
import sun.security.x509.InvalidityDateExtension;
public class BigInteger {
boolean negative;
int numDigits;
DigitNode front;
public BigInteger() {
negative = false;
numDigits = 0;
front = null;
}
public static BigInteger parse(String integer)
throws IllegalArgumentException {
int a = 0;
int b = 0;
this.front = new DigitNode(1, null);
int length = integer.length();
while (length > 0 && a <= length) {
if (integer.charAt(a) == '-') {
this.negative = true;
a++;
}
if (integer.charAt(a) == ' ' && this.numDigits == 0) {
a++;
}
if (integer.charAt(a) == ' ' && this.numDigits == 0) {
a++;
continue;
}
if (Character.isDigit(integer.charAt(a))) {
if(integer.charAt(a) == ' ' && this.numDigits == 0) {
a++;
continue;
}
this.numDigits = this.numDigits + 1;
}
/* IMPLEMENT THIS METHOD */
}
// following line is a placeholder for compilation
return null;
}
DigitNode.java (The class that encapsulates the linked list, NOT ALLOWED TO EDIT THIS)
package bigint;
public class DigitNode {
int digit;
DigitNode next;
DigitNode(int digit, DigitNode next) {
this.digit = digit;
this.next = next;
}
public String toString() {
return digit + "";
}
}
BigTest.java (The tester class that tests whether the parse/add/multiply methods word, NOT ALLOWED TO EDIT THIS)
package bigint;
import java.io.IOException;
import java.util.Scanner;
public class BigTest {
static Scanner sc;
public static void parse()
throws IOException {
System.out.print("\tEnter integer => ");
String integer = sc.nextLine();
try {
BigInteger bigInteger = BigInteger.parse(integer);
System.out.println("\t\tValue = " + bigInteger);
} catch (IllegalArgumentException e) {
System.out.println("\t\tIncorrect Format");
}
}
public static void add()
throws IOException {
System.out.print("\tEnter first integer => ");
String integer = sc.nextLine();
BigInteger firstBigInteger = BigInteger.parse(integer);
System.out.print("\tEnter second integer => ");
integer = sc.nextLine();
BigInteger secondBigInteger = BigInteger.parse(integer);
BigInteger result = BigInteger.add(firstBigInteger,secondBigInteger);
System.out.println("\t\tSum: " + result);
}
public static void multiply()
throws IOException {
System.out.print("\tEnter first integer => ");
String integer = sc.nextLine();
BigInteger firstBigInteger = BigInteger.parse(integer);
System.out.print("\tEnter second integer => ");
integer = sc.nextLine();
BigInteger secondBigInteger = BigInteger.parse(integer);
BigInteger result = BigInteger.multiply(firstBigInteger,secondBigInteger);
System.out.println("\t\tProduct: " + result);
}
public static void main(String[] args)
throws IOException {
// TODO Auto-generated method stub
sc = new Scanner(System.in);
char choice;
while ((choice = getChoice()) != 'q') {
switch (choice) {
case 'p' : parse(); break;
case 'a' : add(); break;
case 'm' : multiply(); break;
default: System.out.println("Incorrect choice");
}
}
}
private static char getChoice() {
System.out.print("\n(p)arse, (a)dd, (m)ultiply, or (q)uit? => ");
String in = sc.nextLine();
char choice;
if (in == null || in.length() == 0) {
choice = ' ';
} else {
choice = in.toLowerCase().charAt(0);
}
return choice;
}
}
However, I get the errors of:
java: non-static variable this cannot be referenced from a static context,
For any this.numDigits or this.front or this.negative.
Whenever I try to increase numDigits, or change the value of the integer to positive, it happens. Somebody please help, Data Structures is really kicking my butt right now.
this refers to the instance that is calling a method. Static methods do not have an associated instance (generally shouldn't be called from an instance at all), and therefore there is no this instance.
However, you can create an instance inside of your static method and affect its fields, for example:
public static BigInteger parse(String integer)
throws IllegalArgumentException {
BigInteger parsedBI = new BigInteger();
//...
parsedBI.front = new DigitNode(1, null);
//...
parsedBI.numDigits = parsedBI.numDigits + 1;
//...
}
Also (I'm one to talk as an SO noob myself), avoid giving more code in your questions than is needed (minimal reproducible example).
public static BigInteger parse(String integer)
The parse method is defined as a static function, so it doesn't have access to any BigInteger instance. "this" is meaningless. No instance has been created yet.
You could create a new BigInteger instance inside of parse method. That object would then have access to its instance variables like numDigits.
bi = new BigInteger()
Then you can access bi.numDigits rather than this.numDigits which doesn't make sense. Here bi points to an object instance of BigInteger whereas this doesn't point to anything because we're not inside an instance, we're in a static method.
Think of the static parse method as just a helper function that in theory could've resided somewhere outside the class definition, but is inside the class definition for convenience and clarity. Its job is to create a BigInteger instance by parsing text.
Related
I have this homework assignment to make a recursive method to crack a password of a given length, n (unlimited and unknown!) made of small English letters, a-z ONLY.
Here's the class "Password" that creates a random password:
import java.util.Random;
public class Password {
private String _password = "";
public Password(int length) {
Random generator = new Random();
for (int i = 0; i < length; ++i) {
this._password = this._password + (char) (generator.nextInt(26) + 97);
}
}
public boolean isPassword(String st) {
return st.equals(this._password);
}
public String getPassword() {
return this._password;
}
}
And here is the question in detail:
"You must write a static recursive method,
public static String findPassword(Password p, int length) that "cracks" the code.
Here's an example of a main method:
public class Main {
public static void main(String[] args) {
Password p = new Password(5);
System.out.println(p.getPassword());
System.out.println(Ex14.findPassword(p, 5));
}
}
Important notes:
The method MUST be recursive, without using ANY loops.
You may not use the getPassword method.
If you would like to use a method of the String class, you may only use the following: charAt, substring, equals, length.
You MAY use overloading, but you MAY NOT use other methods. (You cannot use String.replace/String.replaceall)
You MAY NOT use static(global) variables.
You MAY NOT use any Array. "
Here's what I have until now, which clearly doesn't work; :\
public static String findPassword(Password p, int length) {
return findPassword(p, length, "", 'a');
}
public static String findPassword(Password p, int length, String testPass, char charToChange) {
int currDig = testPass.length() - 1;
if (p.isPassword(testPass))
return testPass;
if (length == 0) // There is no password.
return ""; // Returns null and not 0 because 0 is a password.
if (length > testPass.length())
return findPassword(p, length, testPass + charToChange, charToChange);
if (testPass.length() == length) {
//TODO if charToChange is 'z', then make it the one before it '++', and reset everything else to a.
//if (charToChange == 'z') {
// charToChange = 'a';
// String newString = testPass.substring(0, currDig-1) +
// (charToChange++)
// +testPass.substring(currDig+1,testPass.length()-1);
System.out.println("it's z");
// TODO currDig --;
// String newerString = testPass.substring(0, currDig - 1)
// + (char) (testPass.charAt(testPass.length() - 1) - 25);
// currDig--;
}
return "";
}
Thank you very much! much appreciated!
- TripleS
I have a repository class that uses text files(a requirement), meaning that I have to read strings and cast them in order to instantiate objects. The problem is that I want my repository class as general as I can make it, in order to use it to manipulate different object types.
So, is there a (more elegant) way to dynamically cast strings to whatever field (primitive) type it needs at runtime, while avoiding lots of
try-catch structures with numerous ifs/switches?
As a short simplified version, I want objectA.txt to contain only objectA's information, similarly for objectB.txt, and my Repository code to handle both:
Repository repoA = new Repository("objectA.txt", < list of Types for A >); TypeA a=repoA.getOne();
Repository repoB = new Repository("objectB.txt", < list of Types for B >); TypeB b=repoB.getOne();
What I have:
public class FileRepository extends InMemoryRepository{
private String fileName;
private List<Class> types;
public FileRepository(String fileName, List<Class> types) {
//#param types
// - list containing the Class to be instantiated followed by it's field types
super();
this.fileName = fileName;
this.types=types;
loadData();
}
private void loadData() {
Path path = Paths.get(fileName);
try {
Files.lines(path).forEach(line -> {
List<String> items = Arrays.asList(line.split(","));
//create Class array for calling the correct constructor
Class[] cls=new Class[types.size()-1];
for (int i=1; i<types.size(); i++){
cls[i-1]=types.get(i);
}
Constructor constr=null;
try {
//get the needed constructor
constr = types.get(0).getConstructor(cls);
} catch (NoSuchMethodException e) {
//do something
e.printStackTrace();
}
//here is where the fun begins
//#arg0 ... #argn are the primitives that need to be casted from string
//something like:
//*(type.get(1))* arg0=*(cast to types.get(1))* items.get(0);
//*(type.get(2))* arg1=*(cast to types.get(2))* items.get(1);
//...
Object obj= (Object) constr.newInstance(#arg0 ... #argn);
});
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
P.S.: I'm a JAVA newbie, so please keep the explanations as simple as possible.
No IDE on hand, so I hope this makes sense:
private static final Map<Class, Function<String, ?>> parsers = new HashMap<>();
static {
parsers.put(Long.class, Long::parseLong);
parsers.put(Integer.class, Integer::parseInt);
parsers.put(String.class, String::toString);
parsers.put(Double.class, Double::parseDouble);
parsers.put(Float.class, Float::parseFloat);
// add your own types here.
}
public <T> T parse(Class<T> klass, String value) {
// add some null-handling logic here? and empty values.
return (T)parsers.get(klass).apply(value);
}
Then when you need to create the parameters for your constructor:
parameters =
IntStream
.range(0, cls.size-1)
.map(i -> (Object)parse(types.get(i), items.get(i)))
.toArray(Object[]::new);
I think you can make use of auto-boxing and auto-unboxing coupled with the observation that all wrapper classes provide a method named valueOf that accepts a String and returns an instance of the respective (wrapper) type such that the given string represents the legal value of that type.
The following is an attempt of a type-safe implementation that suits your needs:
import java.io.*;
import java.lang.reflect.*;
import java.util.*;
import java.util.function.Consumer;
/**
* Created by kmhaswade on 3/18/16.
*/
//#ThreadUnsafe
public class NonStreamingGenericPrimitiveDataRepo<T> implements Iterable<T> {
#Override
public Iterator<T> iterator() {
return new Iterator<T>() {
#Override
public boolean hasNext() {
return theIterator.hasNext();
}
#Override
public T next() {
String next = theIterator.next();
try {
Method m = theType.getDeclaredMethod("valueOf", String.class);
return (T) m.invoke(null, next);
} catch (NoSuchMethodException | IllegalAccessException e) {
throw new RuntimeException("This is impossible!");
} catch (InvocationTargetException e) {
throw new RuntimeException("data: " + next + " does not represent type: " + theType);
}
}
};
}
#Override
public void forEach(Consumer<? super T> action) {
throw new RuntimeException("left as an exercise :-) ");
}
private final ArrayList<String> theCache;
private final Iterator<String> theIterator;
private final Class<T> theType;
public NonStreamingGenericPrimitiveDataRepo(Reader reader, Class<T> theType) throws IOException {
Objects.requireNonNull(reader);
Objects.requireNonNull(theType);
if (Integer.class.equals(theType)
|| Long.class.equals(theType)
|| Float.class.equals(theType)
|| Double.class.equals(theType)
|| Boolean.class.equals(theType)
|| String.class.equals(theType)) {
theCache = new ArrayList<>();
try (BufferedReader br = new BufferedReader(reader)) {
String line;
while ((line = br.readLine()) != null)
theCache.add(line);
}
theIterator = theCache.iterator();
this.theType = theType;
} else {
throw new IllegalArgumentException("Not a wrapper type: " + theType);
}
}
public static void main(String[] args) throws IOException {
for (int i : new NonStreamingGenericPrimitiveDataRepo<>(ints(), Integer.class))
System.out.println("read an int: " + i);
for (float f : new NonStreamingGenericPrimitiveDataRepo<>(floats(), Float.class))
System.out.println("read a float: " + f);
for (boolean b: new NonStreamingGenericPrimitiveDataRepo<>(booleans(), Boolean.class))
System.out.println("read a boolean: " + b);
}
static StringReader ints() {
return new StringReader("1.w\n2\n-3\n4\n");
}
static StringReader floats() {
return new StringReader("1.0f\n3.25f\n-3.33f\n4.44f\n");
}
static StringReader booleans() {
return new StringReader("false \ntrue\n");
}
}
If you want to identify the type of primitive data type from a String, you can use the following:
public class Test {
final static String LONG_PATTERN = "[-+]?\\d+";
final static String DOUBLE_PATTERN = "[-+]?(\\d*[.])?\\d+";
final static String BOOLEAN_PATTERN = "(true|false)";
final static String CHAR_PATTERN = "[abcdefghijklmnopqrstuvwxyz]";
public static void main(String[] args) {
String[] xList= {
"1", //int
"111111111111", //long
"1.1", //float
"1111111111111111111111111111111111111111111111111111.1", //double
"c", //char
"true", //boolean
"end" //String
};
for (String x: xList){
if(x.matches(LONG_PATTERN)){
long temp = Long.parseLong(x);
if (temp >= Integer.MIN_VALUE && temp <= Integer.MAX_VALUE){
System.out.println( x + " is int use downcast");
} else {
System.out.println( x + " is long");
}
} else if(x.matches(DOUBLE_PATTERN)){
double temp = Double.parseDouble(x);
if (temp >= Float.MIN_VALUE && temp <= Float.MAX_VALUE){
System.out.println( x + " is float use downcast");
} else {
System.out.println( x + " is Double");
}
} else if (x.toLowerCase().matches(BOOLEAN_PATTERN)){
boolean temp = x.toLowerCase().equals("true");
System.out.println(x + " is Boolean");
} else if(x.length() == 1){
System.out.println(x + " is char");
}else {
System.out.println( x + " is String");
}
}
}
}
Output:
1 is int use downcast
111111111111 is long
1.1 is float use downcast
1111111111111111111111111111111111111111111111111111.1 is Double
c is char
true is Boolean
end is String
The above code categorizes your String in 4 major parts long integer, double, boolean and if none matches then String. As java states, primitive data types fall in two categories:
Integers
byte
char (represented as a character)
short
int
long
Floating point numbers
float
double
Boolean
boolean
This way you will be able to identify the types in which your String lies. You can modify the code to check the range and type cast the numbers accordingly in byte and short as well.
We have an assignment for an intro to java class im taking that requires us to program a parrot.
Essentially we have an output
" What do you want to say?
The User types in his input
" Blah Blah Blah"
And then the parrot is supposed to repeat
"Blah Blah Blah"
I have achieved this.
package parrot;
import java.util.Scanner;
public class Parrot {
public static void main(String[] args) {
System.out.print(" What do you want to say? ");
Scanner input = new Scanner(System.in);
String Parrot = input.nextLine();
System.out.println("Paulie Says: " + Parrot);
}
}
This gives me the exact results I need, but then I read in the lab instructions it wants us to do it in 2 files?
Add 2 files to the project: Parrot.java and ParrotTest.java
In Parrot.java do the following:
Create a public class called Parrot
Inside the class create a public method called speak. The method speak has one String parameter named word and no return value (i.e. return type void) The method header looks like this: public void speak(String word)
The parrot repeats anything he is told. We implement this behavior by printing the word passed as an argument
And what I think im being asked to do is call it from another file? Can someone explain to me how to do this as im not exactly sure whats going on?
Yes your program performs the given task, but not in the manner you are asked. Your main method should be executed from inside the ParrotTest.java file. In this file (ParrotTest.java), you will need to create an instance of a class (you can call it Parrot) by calling a constructor.
Inside your Parrot.java you will create a method called 'speak' which accepts String word.
Going back to the main method: Here you will ask for user input, capture the input in a String 'word' and pass it as an argument to the speak method you created. Once your method has this argument, you can print it's content out to the console.
Parrot would have the following
public class Parrot
{
public void speak( String word )
{
System.out.printf("%s", word);
}
}
Parrot Test would have the following
import java.util.Scanner;
public class ParrotTest
{
public static void main(String[] args)
{
Scanner input = new Scanner(System.in);
System.out.print("What would you like to say to the parrot?: ");
String words = input.nextLine();
Parrot myParrot = new Parrot();
myParrot.speak(words);
}
}
I don't know if you have to use scanner but this is how i would do it.BTW this code works with Jcreator.
public static void main(String[] args) {
String say = IO.getString("Say something") // This is asking the user to say something
System.out.print(name);
}
If you want it to loop 10 times then
then do this
public static void main(String[] args) {
String say = IO.getString("Say something"); // This is asking the user to say something
int count = 10; // it will loop 10 times
while (count >= 10) {
System.out.print(name);
say = IO.getString("Say something");
count++;
}
By the way if you don't have IO class you can you this. Just copy this code into jcreator and say it where you save all your codes.
/**
* #(#)IO.java
* This file is designed to allow HCRHS students to collect information from the
* user during Computer Science 1 and Computer Science 2.
* #author Mr. Twisler, Mr. Gaylord
* #version 2.01 2014/12/21
* *Updated fix to let \t work for all input/output
* *Added input methods to allow for console input
* *Allowed all get methods to work with all objects
* *Updated format methods to use String.format()
*/
import javax.swing.JOptionPane;
import javax.swing.JTextArea;
import java.util.Scanner;
import java.util.InputMismatchException;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
public class IO {
// Shows a message in a popup window
public static void showMsg(Object obj) {
JTextArea text = new JTextArea(obj.toString());
text.setBorder(null);
text.setOpaque(false);
text.setEditable(false);
//String text = obj.toString().replace("\t", " ");
JOptionPane.showMessageDialog(null, text, "HCRHS",
JOptionPane.PLAIN_MESSAGE);
}
/*********************************User Input Methods***************************
* All user input methods get the data type mentioned in their name and return
* a default value if the user enters an incorrect responce.
******************************************************************************/
// Returns String typed by user, default value is ""
public static String getString(Object obj) {
JTextArea text = new JTextArea(obj.toString());
text.setBorder(null);
text.setOpaque(false);
text.setEditable(false);
//String text = obj.toString().replace("\t", " ");
String ans = JOptionPane.showInputDialog(null, text, "HCRHS",
JOptionPane.QUESTION_MESSAGE);
if(ans == null) {
return "";
}
return ans;
}
public static String nextString() {
Scanner scan = new Scanner(System.in);
String ans = scan.nextLine();
scan.close();
if(ans == null) {
return "";
}
return ans;
}
// Returns int typed by the user, default value is 0
public static int getInt(Object obj) {
JTextArea text = new JTextArea(obj.toString());
text.setBorder(null);
text.setOpaque(false);
text.setEditable(false);
//String text = obj.toString().replace("\t", " ");
try {
return Integer.parseInt(JOptionPane.showInputDialog(null, text,
"HCRHS", JOptionPane.QUESTION_MESSAGE));
} catch (NumberFormatException e) {
//System.out.println("Not a valid int");
return 0;
}
}
public static int nextInt() {
Scanner scan = new Scanner(System.in);
int ans;
try {
ans = Integer.parseInt(scan.nextLine());
} catch (NumberFormatException e) {
//System.out.println("Not a valid int");
ans = 0;
}
scan.close();
return ans;
}
// Returns double typed by the user, default value is 0.0
public static double getDouble(Object obj) {
JTextArea text = new JTextArea(obj.toString());
text.setBorder(null);
text.setOpaque(false);
text.setEditable(false);
//String text = obj.toString().replace("\t", " ");
try {
return Double.parseDouble(JOptionPane.showInputDialog(null, text,
"HCRHS", JOptionPane.QUESTION_MESSAGE));
} catch (NumberFormatException|NullPointerException e) {
//System.out.println("Not a valid double");
return 0;
}
}
public static double nextDouble() {
Scanner scan = new Scanner(System.in);
double ans;
try {
ans = Double.parseDouble(scan.nextLine());
} catch (NumberFormatException|NullPointerException e) {
//System.out.println("Not a valid double");
ans = 0;
}
scan.close();
return ans;
}
// Returns char typed by the user, default value is ' '
public static char getChar(Object obj) {
JTextArea text = new JTextArea(obj.toString());
text.setBorder(null);
text.setOpaque(false);
text.setEditable(false);
//String text = obj.toString().replace("\t", " ");
try {
return JOptionPane.showInputDialog(null, text, "HCRHS",
JOptionPane.QUESTION_MESSAGE).charAt(0);
} catch (NullPointerException|StringIndexOutOfBoundsException e) {
//System.out.println("Not a valid char");
return ' ';
}
}
public static char nextChar() {
Scanner scan = new Scanner(System.in);
char ans;
try {
ans = scan.nextLine().charAt(0);
} catch (NullPointerException|StringIndexOutOfBoundsException e) {
//System.out.println("Not a valid char");
ans = ' ';
}
scan.close();
return ans;
}
// Returns boolean typed by the user, default value is false
public static boolean getBoolean(Object obj) {
JTextArea text = new JTextArea(obj.toString());
text.setBorder(null);
text.setOpaque(false);
text.setEditable(false);
//String text = obj.toString().replace("\t", " ");
int n = JOptionPane.showOptionDialog(null, text, "HCRHS",
JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE,
null, new Object[]{"True", "False"}, 1);
return (n == 0);
}
public static boolean nextBoolean() {
Scanner scan = new Scanner(System.in);
String bool = scan.nextLine().toLowerCase();
scan.close();
if (bool.equals("true") || bool.equals("t") || bool.equals("1")) {
return true;
} else {
return false;
}
}
/******************************Formatting Methods******************************
* Format is overloaded to accept Strings/int/double/char/boolean
******************************************************************************/
public static String format(char just, int maxWidth, String s) {
if (just == 'l' || just == 'L') {
return String.format("%-" + maxWidth + "." + maxWidth + "s", s);
} else if (just == 'r' || just == 'R') {
return String.format("%" + maxWidth + "." + maxWidth + "s", s);
} else if (just == 'c' || just == 'C') {
return format('l', maxWidth, format('r',
(((maxWidth - s.length()) / 2) + s.length()), s));
} else {
return s;
}
}
public static String format(char just, int maxWidth, int i) {
return format(just, maxWidth, String.format("%d", i));
}
public static String format(char just, int maxWidth, double d, int dec) {
return format(just, maxWidth, String.format("%,." + dec + "f", d));
}
public static String format(char just, int maxWidth, char c) {
return format(just, maxWidth, String.format("%c", c));
}
public static String format(char just, int maxWidth, boolean b) {
return format(just, maxWidth, String.format("%b", b));
}
/*********************************Fancy Expirmental Methods********************/
public static String choice(String... options) {
String s = (String)JOptionPane.showInputDialog(null,
"Pick one of the following", "HCRHS",
JOptionPane.PLAIN_MESSAGE, null, options, null);
//If a string was returned, say so.
if ((s != null) && (s.length() > 0)) {
return s;
}
return "";
}
public static String readFile(String fileName) {
String ans ="";
try {
Scanner scanner = new Scanner(new File(fileName));
scanner.useDelimiter(System.getProperty("line.separator"));
while (scanner.hasNext()) {
ans += scanner.next()+"\n";
}
scanner.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return ans;
}
public static void writeFile(String fileName, String data) {
try {
FileWriter fw = new FileWriter(fileName, true);
fw.write(data);
fw.close();
} catch(java.io.IOException e) {
e.printStackTrace();
}
}
}
I want to convert String input into int using recursion. This is the code I came up with but if my input is 123456 it only returns 124. If I enter 1234567, it gives an error.
import java.util.*;
public class Problem1 {
static int x =0;
static int counter = 0;
//input
public static void main(String[] args) {
Scanner scan = new Scanner (System.in);
String s= scan.nextLine();
System.out.println(recursive(s));
}
//recursive method
public static int recursive(String s){
if(s.length()==1){
x=(x*10)+ Integer.parseInt(s.substring(0,1));
return x;
}
else{
x = (x*10)+Integer.parseInt(s.substring(0,1));
counter++;
return recursive(s.substring(counter,s.length()-1));
}
}
}
import java.util.Scanner;
public class Problem1 {
static int x = 0;
static int counter = 0;
// input
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
String s = scan.nextLine();
System.out.println(recursive(s));
}
// recursive method
public static int recursive(String s) {
if (s.length() == 1) {
x = (x * 10) + Integer.parseInt(s.substring(0, 1));
return x;
} else {
x = (x * 10) + Integer.parseInt(s.substring(0, 1));
counter++;
return recursive(s.substring(1, s.length()));
}
}
}
Look at your static counter variable. You are incrementing it every time. But you only want to have the substring starting at 1 (so cut off the first "letter").
So instead of using:
counter++;
return recursive(s.substring(counter,s.length()-1));
consider using:
return recursive(s.substring(1)); // you even don't really need the length
Because the String s parameter is as follows:
1st call: 1234567
2nd call: 234567
3rd call: 34567
4th call: 4567
...
So, you only have to cut off the first letter.
Btw: your sample "project" is a really funny one ;)
A few notes to start:
If you're doing recursion, you probably don't want to use a member variable. It's not wrong to do so, but not really typical of the pattern (your x variable).
It's often handy to pass in state through the recursion, although you wouldn't have to (that is, current value of x).
Your case is a little odd because you have to change your current parse value for every sub-parse (shifting by 10 each time); makes it a little more complicated.
If you are going to keep x as a member variable (which does seem to make sense in this case), you don't need to return anything from recursive.
Can you really not just use Integer.parseInt()?
Code could be much more simple, something like:
void recursive (String s)
{
if (s.length() == 0) return 0;
x = x * 10 + Integer.parseInt(s.substring(0, 1));
recursive(s.substring(1));
}
recursion("1234567", 0, 1)
The above code will turn the string "1234567" into an int using recursion. You must pass the string you want to convert, and then 0 and 1.
public static int recursion(String s, int result, int place) {
result += place * Integer.parseInt(s.charAt(s.length() - 1) + "");
if(s.length() == 1) {
return result;
}
else {
return recursion(s.substring(0, s.length() - 1), result, place * 10);
}
}
public static int computeStr(String str) {
if (str.equals("")) {
return 0;
}
int x = 1;
for (int i = 0; i < str.length() - 1; i++) {
x = x * 10;
}
x = x * Integer.parseInt(str.substring(0, 1));
return x + computeStr(str.substring(1));
}
For example: "2432" is (2 * 1000) + (4 * 100) + (3*10) + (2*1) = 2432
this algorithm begins at first position (2) from 2432
I know its kind of a late response but you could try something like this :-
private static int stringToInt(String string) {
if (string.length() == 0) {
return 0;
}
int rv;
int num = string.charAt(string.length() - 1) - '0';
String restOfTheString = string.substring(0, string.length() - 1);
rv = stringToInt(restOfTheString) * 10 + num;
return rv;
}
Try something like this:
Subtracting the ASCII code of the '0' character from your character returns an integer:
public class StringRecursion {
static int counter = 0;
public static void main(String[] args) {
System.out.println(convertStringToInt("123456"));
}
public static int convertStringToInt(String input) {
if (input.length() == 1)
return input.charAt(0) - '0';
int value = convertStringToInt(input.substring(0, input.length() - 1));
counter++;
return value * 10 + input.charAt(counter) - '0';
}
}
Try it like this :
public static int conStrToInt(String str) {
if(str.length()==0)
{
return 0;
}
char cc = str.charAt(0);
String ros = str.substring(1);
int factor=1;
for(int i=0;i<str.length()-1;i++)
factor*=10;
factor=factor*(cc-'0');
return factor+conStrToInt(ros);
}
I have a problem about the last part of the code. I want to assign numbers to specific words but i always get 0 value, even though I get those strings from the first System.out.println correctly, i cannot get the numerical equivalents of those strings at the second System.out.println.Any ideas how to solve this problem?
public static double number;
protected void myMethod(HttpServletRequest request, HttpServletResponse response) {
String speech= request.getParameter("speech");
System.out.println("The recognized speech is : "+ speech);
// There is no problem till here.
if(speech == "Hi")
number = 1 ;
if(speech== "Thanks")
number = 2 ;
if(speech== "Bye")
number = 0 ;
System.out.println("The number for the speech is : " + number);
}
However here i dont get the correct numbers but only 0 for each word!
The == will only be true if the Strings are the same object. Use:
if(speech.equals("Hi"))
or to match without case:
if(speech.equalsIgnoreCase("hi"))
You can't use the == operator to check if two Strings have the same value in Java, you need to use the .equals() or equalsIgnoreCase() methods instead:
if("Hi".equalsIgnoreCase(speech)) {
number = 1;
}
else if("Thanks".equalsIgnoreCase(speech)) {
number = 2;
}
else if("Bye".equalsIgnoreCase(speech)) {
number = 0;
}
else {
number = -1;
}
The reason for this is that the == operator compares references; that is it will return true if and only if the instance stored in variable speech is the same instance as the literal String you've created between double quotes ("Hi", "Thanks", or "Bye").
Note also that I use the equalsIgnoreCase() call on the literal String I'm declaring, rather than the variable that is assigned from the parameter. This way, if a speech == null, the method call is still valid ("Hi" will always be a String), and so you won't get a NullPointerException, and the flow will continue until the else branch.
Try the following snippet:
Main.java
public class Main {
public static void main(String[] args) {
List<StringWithValue> stringList = new ArrayList<StringWithValue>();
stringList.add(new StringWithValue("Hi", 1));
stringList.add(new StringWithValue("Thanks", 2));
stringList.add(new StringWithValue("Bye", 3));
String speech = "Hi";
int number = 0;
for(StringWithValue swv : stringList){
if(swv.getString().equals(speech)){
number = swv.getValue();
break;
} else {
number = -1;
}
System.out.println("The number for the speech is : " + number);
}
}
StringWithValue.java
public class StringWithValue {
private String string;
private int value;
public StringWithValue(String string, int value) {
this.string = string;
this.value = value;
}
public String getString() {
return string;
}
public int getValue() {
return value;
}
}
public static double number;
if(speech=="hi")
{
number=1;
}
else if(speech=="thanks")
{
number=2;
}
else if(speech=="Bye")
{
number=0;
}
else
{
System.out.println("Word Not Found");
}