Java get new number but ignore numbers in front of letters - java

I am trying to think of a way to resolve my problem. I didn't found the perfect solution I hope someone here can help me out.
So, I have an array of identifier numbers like:
...
3113,
3114,
3115 A1,
3115 A2,
3116
...
I want to return the next number available to insert.
Currently Im using this function but for some reason it dont work I think because it is reading the number 3115 A1 as 31151.
In this example I want to return 3117.
Here's the function in JAVA:
public String getNewNumber(){
int lastNumber = 1;
for(String number : listNumbers){
if(Integer.parseInt(number.replaceAll("[^\\d.]", "")) > lastNumber){
lastNumber = Integer.parseInt(number);
}
}
int newNumber = lastNumber + 1;
return newNumber + "";
}

Instead of replacing the letters you should extract the number with split, this removes a lot of possible bugs when the string changes. This requires the first number in the string to be the one you want to extract.
public String getNewNumber(String[] listNumbers) {
int lastNumber = 1;
for (String listNumber : listNumbers) {
String splitNumber = listNumber.split("\\D")[0];
int parsedNumber = Integer.parseInt(splitNumber);
if(parsedNumber > lastNumber) {
lastNumber = parsedNumber;
}
}
int newNumber = lastNumber + 1;
return String.valueOf(newNumber);
}

number.replaceAll("[^\\d.]", "")
It will replace all non-digit number from the string, so 3115 A1 becomes 31151. So instead of replacing all non digit character from input number, find first non-digit character and take substring.
String getNewNumber(String[] listNumbers) {
int lastNumber = 1;
for (String number : listNumbers) {
int index = firstNonDigitIndex(number);
int numberInt = Integer.parseInt(number.substring(0, index));
if (numberInt > lastNumber) {
lastNumber = numberInt;
}
}
int newNumber = lastNumber + 1;
return Integer.toString(newNumber);
}
/**
* Returns index of first non-digit char in string or str.length()
*/
int firstNonDigitIndex(String str) {
for (int i = 0; i < str.length(); i++) {
if (!Character.isDigit(str.charAt(i))) {
return i;
}
}
return str.length();
}
Also if your input listNumbers is sorted (it seems from your example), so you don't need to iterate all numbers, just parse the last number.

Related

Recusion - calculating sum of digits in a mixed string. (homework dead end)

I've got into a dead end while trying to fix some lines
in my code.
The task is writing a Recursion function which takes a string and calculating
the sum of the numbers in it.
For example -
input - "5a-f5-11"
output- The numbers are 5, 5 and 11, therefore the sum is 21.
the Catch in this task is to sum numbers that are more than one digit.
(11 in our case)
I have not planned to use Char arrays or anything, but working with strings in some lines made it difficult.
My code doesn't compile so far but i'm sure the logic is in the right spot - (i made a helper function, which means its not the final function but its doing the main work).
public static int sumNumbersInText(String str, int i, String subStr, int sum) {
if(str.length() >= i) return sum;
char[] array = new char[str.length()];
str.getChars(0, str.length(), array, 0);
char oneStr = array[i];
String newSubStr = subStr;
if(Character.isDigit(oneStr)); //if the new index is not a number and the index before IS a number>
{
if(Character.isDigit(subStr));// new index IS a number, therefore will sum up.
{
int num = 0;
sum+=num;
newSubStr = "";
}
}
else
{
newSubStr += oneStr;
}
return sumNumbersInText(str, i+1, subStr, sum);
}
This is how I'd approach it:
public class AddMultipleDigitsInStringRecursive
{
public static void main(String[] args)
{
String input = "5a-f5-11";
System.out.println("Input: " + input);
int sum = sumDigits(input);
System.out.println("Sum: " + sum);
}
public static int sumDigits(String input)
{
return addDigits(input, 0, "");
}
private static int addDigits(String input, int index, String curNumber)
{
if(index < input.length())
{
int curSum = 0;
String curChar = input.substring(index, index + 1); // get the current character (as a String)
if (Character.isDigit(curChar.charAt(0))) // if it's a digit, append it to the current number
{
curNumber = curNumber + curChar;
}
else // it's not a digit, do we have a number pending?
{
if (!curNumber.isEmpty())
{
curSum = Integer.parseInt(curNumber); // convert current number to an Integer
}
curNumber = ""; // reset the current number so we can accumulate more digits when they are found
}
// return the sum of the current number (if any) with any other numbers that are found
return curSum + addDigits(input, index + 1, curNumber);
}
else // reached the end of the string; was there a number pending?
{
int curSum = 0;
if (!curNumber.isEmpty())
{
curSum = Integer.parseInt(curNumber);
}
return curSum;
}
}
}
Somehow managed to figure it out, it actually works:
public static int sum(String str, int i, String subStr, int sum) {
if(str.length() <= i) return sum;
String newSubStr = subStr;
char oneStr = str.charAt(i);
if(!Character.isDigit(oneStr)) //if the new index is not a number and the index before IS a number>
{
if(isNumeric(subStr))// new index IS a number, therefore will sum up.
{
int num = Integer.parseInt(subStr);
sum+=num;
newSubStr = "";
}
}
else
{
String temp = oneStr+"";
newSubStr += temp;
}
System.out.println(sum);
return sum(str, i+1, newSubStr, sum);
}
Well, here is one simple way of using recursion to solve the problem. I used a regular expression to grab the numbers since you didn't indicate that it was not permitted.
public static int sum(String a) {
Matcher m = Pattern.compile("(\\d\\d+)").matcher(a);
if (m.find()) {
return Integer.parseInt(m.group(1)) + sum(a.substring(m.end()));
}
return 0;
}

Searching for a digit and delete it in my int variable

I want to search a digit in my int variable and delete it.
Here is little part of the code (not finished, because i'm still on the implementation). I noticed that there are many use cases. So do you know an easier way to delete the digit?
public int getStringtoIntForEthType(int OxAB){
String myInt = Integer.toString(OxAB);
if(Integer.toString(OxAB).contains("x")){
myInt = myInt.substring(2);
}
StringBuilder myIntBuilder = new StringBuilder(myInt);
for(int a = 0; a<=myInt.length();a++){
if(a-1 < 0 && myIntBuilder.charAt(0)!=0 && myIntBuilder.charAt(a)==0){
}
}
return Integer.parseInt(myIntBuilder.toString());
}
To delete all existence of that Digit from the number here is a function :-
public int DeleteDigit(int number, int numberToDel)
{
String Num = "" + number;
Num = Num.replace(numberToDel + "", "");
if(Num.length != 0)
return Integer.parseInt(Num);
return 0;
}
this would return an integer without the digit

Breaking string into multiple lines in Java

I have a single line string of length n, which I want to split into maximum of 3 lines. Each line can have a maximum of 45 chars, after which I want to add a new-line char ("\n"). The 3rd line can have a maximum of 42 chars after which I need to include 3 dots (...) if the string goes beyond that, thus making the total characters in the 3rd line 45 as well.
The condition is that the new line character should not be added in the middle of a word. How do I do this efficiently? This operation is just a small part of the entire program, but will be called repeatedly. So I'm not sure if I should actually bother about the efficiency.
What I'm doing right now is that I first figure out where the spaces between words are and then add it to a List. I then iterate through the list and find 3 indices each representing the end word of each line. So the first index will be the space closest to 45, the next closest to 90, and the third closest to 135. I then use these indices to split the actual string, and add "\n" and "..." respectively. This is my code:
//maxCharsPerLine will be 45
public String splitString(String input, int maxCharsPerLine){
String output = "";
ArrayList<Integer> spaces = new ArrayList<Integer>();
// Logic to figure out after which word the sentence should be split so that we don't split in middle of a word
for(int index = 0; index < input.length(); index++){
if(input.charAt(index)==' '){
spaces.add(index);
}
}
//add index of last word of string
spaces.add(input.length());
int index1 = 0; int index2 = 0; int index3 = 0;
for(Integer index : spaces){
// find word closest to and less than maxCharsPerLine. This index will be used to find the last word in line1
if(index<=maxCharsPerLine)
index1 = index;
// find word closest to and less than 2*maxCharsPerLine. This index will be used to find the last word in line2
else if(index<=2*maxCharsPerLine)
index2 = index;
// find word closest to and less than 3*maxCharsPerLine, but exclude 3 chars for adding the dots (...). This index will be used to find the last word in line3
else if(index<=(3*maxCharsPerLine)-3)
index3 = index;
}
if(input.length()>maxCharsPerLine){
if(index1 > 0)
output = input.substring(0, index1);
if(index2 > 0)
output += "\n"+input.substring(index1+1, index2);
if(index3 > 0){
output += "\n"+input.substring(index2+1, index3);
if(input.length()>3*maxCharsPerLine)
output += "...";
}
}
//if length of input is < 45, just return the input
else
output = input;
return output;
}
Not sure in which scenarios this will fail. Is there a better way to do this?
Thanks.
You can use WordUtils.wrap method of Apache Commans Lang if 3 dots are not be considered for wrapping the line.
WordUtils.wrap(str, 45)
Code
public class test3 {
public static void main(String[] args) {
String S = "The condition is that the new line should not be added in the middle of a word. How do I do this efficiently? This operation is just a small part of the entire program, but will be called repeatedly. So I'm not sure if I should actually bother about the efficiency";
String Op = "";
String Op1 = "";
String Op2 = "";
String Op3 = "";
String Temp[] = S.split(" ");
int max_size_1 = 45;
int max_size_2 = 45;
int max_size_3 = 42;
int length = 0;
for (int i = 0; i < Temp.length; i++) {
length = length + Temp[i].length()+1;
if(length <= max_size_1) Op1 = Op1 + Temp[i]+" ";
else if(length <= Op1.length()+max_size_2) Op2 = Op2 +Temp[i]+" ";
else if(length <= Op1.length()+Op2.length()+max_size_3) Op3 = Op3 + Temp[i]+" ";
else {Op3 = Op3 +'\b' + "..."; i =Temp.length ; } //backspace
}
Op = Op1+"\n"+Op2+"\n"+Op3;
System.out.println(Op);
System.out.println(Op1.length()+" "+Op2.length()+" "+Op3.length()+" ");
}}
Output
The condition is that the new line should
not be added in the middle of a word. How do
I do this efficiently? This operation...
42 45 45
Here another solution, though it might be corrupted and needs to be edited.
int sizeOfString = input.lenght();
//the maximum lenght of a String
int aPartialStringLenght = 45;
String firstString;
String secondString;
String thirdString;
for(int x = 1; x <= 3; x++){
// looks for the last space before your 45th character
//sets the lenght for the third String to max. 42characters
if(x == 3){
aPartialStringLenght = 42;
}
while(!input.charAt(aPartialStringLenght*x).equals(" ")){
aPartialStringLenght -=1;
}
switch(x){
// gets the substring till your first partialString
case 1: firstString = input.substring(0, aPartialStringlenght);
aPartialStringLenght = 45;
// gets the substring from the end of your first partialString till the end of your second partialString
case 2: secondString = input.substring(firstString.lenght(), aPartialStringLenght + firstString.lenght());
aPartialStringLenght = 45;
// gets the substring from the end of your second partialString till till the end of your third partialString + "..."
case 3 thirdString = input.substring(firstString.lenght()+secondString.lenght(), aPartialStringLenght + firstString.lenght()+ secondString.lenght() )+"..."
aPartialStringLenght = 45;
}
}
Based on surya answer
public class test3 {
public static void main(String[] args) {
String S = "The condition is that the new line should not be added in the middle of a word. How do I do this efficiently? This operation is just a small part of the entire program, but will be called repeatedly. So I'm not sure if I should actually bother about the efficiency";
String F = WordUtils.wrap(S, 45);
String[] F1 = F.split(System.lineSeparator());
System.out.println(F1[0]);
System.out.println(F1[1]);
F1[2] = F1[2] +'\b'+'\b'+'\b'+"...";
System.out.println(F1[2]);
}
}
Output
The condition is that the new line should not
be added in the middle of a word. How do I do
this efficiently? This operation is jus...
My proposal is highly efficient, because:
It needs just two objects: the final string and a temporary StringBuilder, which is pre-sized,
And it does not waste time in pre-processing: Processes each character just once, and decides on the fly what to do.
And it is also flexible, because all the involved data are received as parameters:
public final class LinesSplitter
{
private LinesSplitter(){}
private static final char NL='\n';
public static String splitInLines(String text, int maxLineLength, int maxLines, String lastLineSuffix)
{
StringBuilder output=new StringBuilder((1 + maxLineLength) * maxLines);
int p=0;
int startOfLine=0;
int lastBlank=0;
int lastNonBlank=0;
int len=text.length();
String neededSuffix=text.length() > maxLineLength * maxLines
? lastLineSuffix
: "";
int lines=0;
while (lines < maxLines && p < len)
{
char c=text.charAt(p);
if (Character.isWhitespace(c))
{
lastBlank=p;
lastNonBlank=1 + p;
}
else if (p < len)
{
int maxLengthForCurrentLine=getMaxLength(maxLineLength, maxLines, 1 + lines, neededSuffix);
if (p - startOfLine == maxLengthForCurrentLine)
{
output.append(text, startOfLine, lastBlank);
String suffix=getSuffix(maxLineLength, maxLines, 1 + lines, neededSuffix);
if (!suffix.isEmpty())
{
output.append(suffix);
}
else
{
output.append(NL);
}
lines++;
startOfLine=lastNonBlank;
}
}
p++;
}
if (lines < maxLines && p - startOfLine > 0)
{
output.append(text, startOfLine, len);
}
return output.toString();
}
private final static int getMaxLength(int maxLineLength, int maxLines, int currentLine, String lastLineSuffix)
{
return currentLine == maxLines
? maxLineLength - lastLineSuffix.length()
: maxLineLength;
}
private final static String getSuffix(int maxLineLength, int maxLines, int currentLine, String lastLineSuffix)
{
return currentLine == maxLines
? lastLineSuffix
: "";
}
}
The only possible drawback is that it does not support several adjacent blanks.

Count occurence of a character in a string

I tried to count the occurrence of alphabets in a string, but I substitue them with numbers to make it clearer. Then when I run that code, it doesnt display the results I want.I dont really know why...Please help!! Thank you so much!!
Scanner Scanner1 = new Scanner(System.in);
out.println("Please type in a string below.");
String UserInput = Scanner1.nextLine();
String Index = "12345";
int length = 2;//Modified
int[] count = new int[length];
int length2 = 5; //Modified
int n1 = 0;
int n2 = 0;
out.println(UserInput.charAt(n1));//Modified
out.println(Index.charAt(n2));//Modified
for (int i = 0; i < length; i++) {
if (UserInput.charAt(n1) == Index.charAt(n2)) {
n1++;
count[length - (length - n1)]++;
} else {
n2++;
if(n2==length2)
{
n2 = n2-length2;
}
}
}
A relatively short and neat way to count a specific character in a string is using the return value of the replaceAll method:
public static int countChar(final String str, final char c) {
return str.replaceAll("[^" + c + "]","").length();
}
The pattern [^x] (x can be replaced with any char (or amount of different chars)) will match everything in a given String except x. So [^T] of TEST would replace E and S with the given replacement (which is "" (nothing)) and keeps the Ts. The method would return TT. If you count that length, you'll receive the count of the searched character of the given string.
The example
System.out.println(countChar("TEST", 'T'));
System.out.println(countChar("TEST", 'E'));
System.out.println(countChar("TEST", 'S'));
prints
2
1
1
(keep in mind that is method is case sensitive)
use collections like Hashmap. Here Character stores every unique character encountered and Integer stores the count of every character whenever it is encountered.

Tokenize EVERY digit in a String number?

I've got this bit of code here:
public class Project1 {
public static void main(String args[])
{
Scanner input = new Scanner(System.in);
System.out.println("Input a binary number");
String binary = input.nextLine();
System.out.println(Conversion(binary));
}
public static int Conversion(String binary)
{
StringTokenizer st = new StringTokenizer(binary, " ");
int n = st.countTokens() - 1; // Used as the power number in b^n for conversion
int result = 0;
while(st.hasMoreTokens()){
int binaryInt = Integer.parseInt(st.nextToken());
result += binaryInt * (1 << n);
n--;
}
return result;
}
}
And it works beautifully... if the input has spaces in between the binary numbers. For example, if the input is 1 1 1 1, then it will rightfully return 15. Cool, but how do I change the tokenizer to not require spaces to split each digit? I tried doing StringTokenizer(binary, ""); and StringTokenizer(binary);, but neither properly split each digit into it's own token.
You will notice that, while StringTokenizer obviously only works with Strings, I've converted the Strings into ints inside my conversion method before returning the result.
# Tony I think you tried to add the ascii values of the digits here
for input value 10
for first run
int binaryInt = binary.char(i) ; so binaryInt would get the value = 49(aski value of char '1')
hence result = 49*2 = 98
in second run
result = 98 + 48 *1 = 146
following function will serve your purpose, for input String "1101" , it returns 13
public int getDecimal(String binaryString){
//binaryString = "1101";
int result = 0;
int n = binaryString.length()-1;
for(int i=0;i<binaryString.length();i++)
{
int num = binaryString.charAt(i);
if(num>=48 && num <=57){
result+=(num-48) * Math.pow(2, n) ;
n --;
}
}
return result;
}
}
How about something like this:
// remove everything that is not a digit
String digitsOnly = binary.replaceAll("[^\\d]","");
//iterate over every digit
for(char digit:digitsOnly.toCharArray()) {
int n = Character.getNumericValue(digit);
// do stuff...
}
If you get a string like "10011010", you don't need a tokenizer, you can just iterate over the string and use charAt:
for (int i = 0; i < s.length(); i++) {
char currentDigit = s.charAt(i);
// Do stuff with the digit
}

Categories