public static String carRentalCode(String licensePlate) {
// precondition: licensePlate is a valid plate as described in pdf
// postcondition: return the car rental code for the licensePlate as described
int values = 0;
int ascii = 0;
int sum = 0;
int convert = 0;
int count = 0;
int a = 0;
char letter;
String license;
char[] ch = new char[licensePlate.length()];
for (int i = 0; i < licensePlate.length(); i++) {
ch[i] = licensePlate.charAt(i);
}
for(int i = 0; i< ch.length; i++)
{
if(Character.isDigit(ch[i]))
{
values += Character.getNumericValue(ch[i]);
}
if(Character.isAlphabetic(ch[i]))
{
ascii += (int) ch[i];
count++;
}
}
sum = values + ascii;
convert = sum%26 + 65;
letter = (char)convert;
String[] letters = licensePlate.split("\\d+");
String lowercase = Arrays.toString(letters).toLowerCase();
String code = Integer.toString(sum);
return letter + code + lowercase;
Here I am supposed to return a car rental code based on a given license plate (the tester plate is "123ABC456"). The only problem I have left is that my lowercase returns as [[,abc]] as opposed to the correct answer which is [abc].
How do you fix the empty space in front, and there being two pairs of brackets instead of one? Or is there any other way to only obtain the letters of a string (ABC), separated from the digits (123 and 456) and return that instead?
Expected: L219[abc]
Actual: L219[[, abc]]
I changed some of your code, use String.toCharArray() to create an array of characters instead of copying it char by char, and replace all your digits by empty string to get only the alphabetic characters
public static String carRentalCode(String licensePlate) {
// precondition: licensePlate is a valid plate as described in pdf
// postcondition: return the car rental code for the licensePlate as described
int values = 0;
int ascii = 0;
int sum = 0;
int convert = 0;
char letter;
char[] ch = licensePlate.toCharArray();
for (int i = 0; i < ch.length; i++) {
if (Character.isDigit(ch[i])) {
values += Character.getNumericValue(ch[i]);
}
if (Character.isAlphabetic(ch[i])) {
ascii += ch[i];
}
}
sum = values + ascii;
convert = sum % 26 + 65;
letter = (char) convert;
String lowercase = licensePlate.replaceAll("\\d+", "").trim().toLowerCase();
String code = Integer.toString(sum);
return letter + code + "[" + lowercase + "]";
}
I just wrote the following code which extracts a word (without a number) from a string:
import java.util.*;
import java.lang.*;
import java.io.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
class Ideone
{
static void extractWord(String str)
{
String regex = "[a-zA-Z]+";
// compiling regex
Pattern p = Pattern.compile(regex);
// Matcher object
Matcher m = p.matcher(str);
while(m.find())
{
System.out.println(m.group());
}
}
public static void main (String[] args)
{
String str = "123ABC456";
extractWord(str);
}
}
Hope this helps you.
Just as an example of a more functional approach:
String lowercase = licensePlate.chars()
.filter(Character::isAlphabetic)
.map(Character::toLowerCase)
.mapToObj(c -> Character.toString((char) c))
.reduce((a, b) -> a + b)
.orElse("");
How about just returning
letter + code + "[" + letters[1].toLowerCase() + "]"
Related
Here's what I have if someone could give me some idea of what to do that would be great. I think taking the index and counting how many values are together would be helpful but im not sure how to implement that. isVowel is a helper method to determine if the char is a vowel.
public static String doubleVowelsMaybe(String s)
{
int run =0;
String n = "";
for(int i = 0; i< s.length(); ++i)
{
char k = s.charAt(i);
if(isVowel(k))
{
}
if(run == 1)
{
n = n + s.substring(i, i+1) + s.substring(i, i+1);
run=0;
}
else
{
n = n + s.substring(i, i+1);
run= 0;
}
}
return n;
Most simple string manipulation tasks like this can be fairly easily done with a regex. This one's a one-liner:
public static String doubleVowelsMaybe(String s) {
return s.replaceAll("(?<![aeiou])([aeiou])(?![aeiou])", "$1$1");
}
The regex works as follows:
(?<![aeiou]) is a negative lookbehind, so it matches only if the character is not preceded by a vowel.
([aeiou]) matches a single vowel, and captures it to group number 1.
(?![aeiou]) is a negative lookahead, so it matches only if the character is not followed by a vowel.
The replacement of $1$1 means two copies of whatever was matched by group number 1, which is the single vowel character.
import java.util.*;
class Hello {
public static void main(String[] args) {
String abc = "beautiful";
String n = "";
int i = 0;
char[] abcchar = abc.toCharArray();
HashSet<Character> hs = new HashSet<>();
hs.add('a');
hs.add('e');
hs.add('i');
hs.add('o');
hs.add('u');
while (i < abcchar.length) {
if (i + 1 < abcchar.length && hs.contains(abcchar[i]) && !hs.contains(abcchar[i + 1])) {
n = n + abc.substring(i, i + 1) + abc.substring(i, i + 1);
} else {
while (hs.contains(abcchar[i])) {
n = n + abc.substring(i, i + 1);
i++;
}
n = n + abc.substring(i, i + 1);
}
i++;
}
System.out.print(n);
}
}
I need to write encryptor.
The first letter needs to be converted to its ASCII code.
The second letter needs to be switched with the last letter
It should make from this "65 119esi 111dl 111lw 108dvei 105n 97n 111ka"
This "A wise old owl lived in an oak"
But when I check is char a digit i have an error.
public static void encryptThis(String text) {
String [] text_arr = text.split("\\s");
for(int i = 0; i < text_arr.length;i++){
String word = text_arr[i];
int length = word.length();
char [] char_word = new char [length];
char_word = word.toCharArray();
int k = 0;
length = char_word.length;
char [] numb = new char [length];
for (int j = 0;j < length; j++){
//In this place
if (Character.isDigit(char_word[i])){
numb[k] = char_word[i];
char_word[i] = ' ';
k++;
System.out.println(numb[k]);
}
}
int number = Integer.parseInt(numb.toString(),8);
String edit_char_word = char_word.toString();
String final_str = new StringBuffer(edit_char_word).reverse().toString().trim();
final_str = number + final_str;
text_arr[i] = final_str;
}
String fin_text = text_arr.toString();
return fin_text;
}
I wrote the encryptThis method from the beginning and tried to stay as simple to get readable code, here is
a full working example. As you did not mention what to do if a number is the first "letter" there is no
special handling for this - an "1" will be encrypted to (ascii) 49...
public class Main_So {
public static void main(String[] args) {
System.out.println("https://stackoverflow.com/questions/62460366/in-function-isdigit-java-lang-arrayindexoutofboundsexception-5");
String input = "A wise old owl lived in an oak";
String outputExpected = "65 119esi 111dl 111lw 108dvei 105n 97n 111ka";
System.out.println("input: " + input);
String output = encryptThis(input);
System.out.println("output encryptThis: " + output);
System.out.println("output expected: " + outputExpected);
}
public static String encryptThis(String text) {
String[] text_arr = text.split("\\s");
String outputString = "";
for (int i = 0; i < text_arr.length; i++) {
String word = text_arr[i];
int length = word.length();
int ascii0 = (int) word.charAt(0);
String word0 = String.valueOf(ascii0); // first char as ascii code
String subString = word.substring(1);
if (length > 2) { // switch chars if string length > 2
char char1 = word.charAt(1);
char charEnd = word.charAt(length - 1);
StringBuilder wordBuilder = new StringBuilder(subString);
wordBuilder.setCharAt(0, charEnd);
wordBuilder.setCharAt((length - 2), char1);
subString = String.valueOf(wordBuilder);
}
outputString = outputString + word0 + subString + " ";
}
return outputString;
}
}
This is the result:
input: A wise old owl lived in an oak
output encryptThis: 65 119esi 111dl 111lw 108dvei 105n 97n 111ka
output expected: 65 119esi 111dl 111lw 108dvei 105n 97n 111ka
I have a string in format AB123. I want to split it between the AB and 123 so AB123 becomes AB 123. The contents of the string can differ but the format stays the same. Is there a way to do this?
Following up with the latest information you provided (2 letters then 3 numbers):
myString.subString(0, 2) + " " + myString.subString(2)
What this does: you split your input string myString at the 2nd character and append a space at this position.
Explanation: \D represents non-digit and \d represents a digit in a regular expression and I used ternary operation in the regex to split charter to the number.
String string = "AB123";
String[] split = string.split("(?<=\\D)(?=\\d)");
System.out.println(split[0]+" "+split[1]);
Try
String a = "abcd1234";
int i;
for(i = 0; i < a.length(); i++){
char c = a.charAt(i);
if( '0' <= c && c <= '9' )
break;
}
String alphaPart = a.substring(0, i);
String numberPart = a.substring(i);
Hope this helps
Although I would personally use the method provided in #RakeshMothukur's answer, since it also works when the letter or digit counts increase/decrease later on, I wanted to provide an additional method to insert the space between the two letters and three digits:
String str = "AB123";
StringBuilder sb = new StringBuilder(str);
sb.insert(2, " "); // Insert a space at 0-based index 2; a.k.a. after the first 2 characters
String result = sb.toString(); // Convert the StringBuilder back to a String
Try it online.
Here you go. I wrote it in very simple way to make things clear.
What it does is : After it takes user input, it converts the string into Char array and it checks single character if its INT or non INT.
In each iteration it compares the data type with the prev character and prints accordingly.
Alternate Solutions
1) Using ASCII range (difficulty = easy)
2) Override a method and check 2 variables at a time. (difficulty = Intermediate)
import org.omg.CORBA.INTERNAL;
import java.io.InputStreamReader;
import java.util.*;
import java.io.BufferedReader;
public class Main {
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
char[] s = br.readLine().toCharArray();
int prevflag, flag = 0;
for (int i = 0; i < s.length; i++) {
int a = Character.getNumericValue(s[i]);
String b = String.valueOf(s[i]);
prevflag = flag;
flag = checktype(a, b);
if ((prevflag == flag) || (i == 0))
System.out.print(s[i]);
else
System.out.print(" " + s[i]);
}
}
public static int checktype(int x, String y) {
int flag = 0;
if (String.valueOf(x).equals(y))
flag = 1; // INT
else
flag = 2; // non INT
return flag;
}
}
I was waiting for a compile to finish before heading out, so threw together a slightly over-engineered example with basic error checking and a test.
import java.text.ParseException;
import java.util.LinkedList;
public class Main {
static public class ParsedData {
public final String prefix;
public final Integer number;
public ParsedData(String _prefix, Integer _number) {
prefix = _prefix;
number = _number;
}
#Override
public String toString() {
return prefix + "\t" + number.toString();
}
}
static final String TEST_DATA[] = {"AB123", "JX7272", "FX402", "ADF123", "JD3Q2", "QB778"};
public static void main(String[] args) {
parseDataArray(TEST_DATA);
}
public static ParsedData[] parseDataArray(String[] inputs) {
LinkedList<ParsedData> results = new LinkedList<ParsedData>();
for (String s : TEST_DATA) {
try {
System.out.println("Parsing: " + s);
if (s.length() != 5) throw new ParseException("Input Length incorrect: " + s.length(), 0);
String _prefix = s.substring(0, 2);
Integer _num = Integer.parseInt(s.substring(2));
results.add(new ParsedData(_prefix, _num));
} catch (ParseException | NumberFormatException e) {
System.out.printf("\"%s\", %s\n", s, e.toString());
}
}
return results.toArray(new ParsedData[results.size()]);
}
}
i have a string containing nested repeating patterns, for example:
String pattern1 = "1234";
String pattern2 = "5678";
String patternscombined = "1234|1234|5678|9"//added | for reading pleasure
String pattern = (pattern1 + pattern1 + pattern2 + "9")
+(pattern1 + pattern1 + pattern2 + "9")
+(pattern1 + pattern1 + pattern2 + "9")
String result = "1234|1234|5678|9|1234|1234|56";
As you can see in the above example, the result got cut off. But when knowing the repeating patterns, you can predict, what could come next.
Now to my question:
How can i predict the next repetitions of this pattern, to get a resulting string like:
String predictedresult = "1234|1234|5678|9|1234|1234|5678|9|1234|1234|5678|9";
Patterns will be smaller that 10 characters, the predicted result will be smaller than 1000 characters.
I am only receiving the cutoff result string and a pattern recognition program is already implemented and working. In the above example, i would have result, pattern1, pattern2 and patternscombined.
EDIT:
I have found a solution working for me:
import java.util.Arrays;
public class LRS {
// return the longest common prefix of s and t
public static String lcp(String s, String t) {
int n = Math.min(s.length(), t.length());
for (int i = 0; i < n; i++) {
if (s.charAt(i) != t.charAt(i))
return s.substring(0, i);
}
return s.substring(0, n);
}
// return the longest repeated string in s
public static String lrs(String s) {
// form the N suffixes
int N = s.length();
String[] suffixes = new String[N];
for (int i = 0; i < N; i++) {
suffixes[i] = s.substring(i, N);
}
// sort them
Arrays.sort(suffixes);
// find longest repeated substring by comparing adjacent sorted suffixes
String lrs = "";
for (int i = 0; i < N - 1; i++) {
String x = lcp(suffixes[i], suffixes[i + 1]);
if (x.length() > lrs.length())
lrs = x;
}
return lrs;
}
public static int startingRepeats(final String haystack, final String needle)
{
String s = haystack;
final int len = needle.length();
if(len == 0){
return 0;
}
int count = 0;
while (s.startsWith(needle)) {
count++;
s = s.substring(len);
}
return count;
}
public static String lrscutoff(String s){
String lrs = s;
int length = s.length();
for (int i = length; i > 0; i--) {
String x = lrs(s.substring(0, i));
if (startingRepeats(s, x) < 10 &&
startingRepeats(s, x) > startingRepeats(s, lrs)){
lrs = x;
}
}
return lrs;
}
// read in text, replacing all consecutive whitespace with a single space
// then compute longest repeated substring
public static void main(String[] args) {
long time = System.nanoTime();
long timemilis = System.currentTimeMillis();
String s = "12341234567891234123456789123412345";
String repeat = s;
while(repeat.length() > 0){
System.out.println("-------------------------");
String repeat2 = lrscutoff(repeat);
System.out.println("'" + repeat + "'");
int count = startingRepeats(repeat, repeat2);
String rest = repeat.substring(count*repeat2.length());
System.out.println("predicted: (rest ='" + rest + "')" );
while(count > 0){
System.out.print("'" + repeat2 + "' + ");
count--;
}
if(repeat.equals(repeat2)){
System.out.println("''");
break;
}
if(rest!="" && repeat2.contains(rest)){
System.out.println("'" + repeat2 + "'");
}else{
System.out.println("'" + rest + "'");
}
repeat = repeat2;
}
System.out.println("Time: (nano+millis):");
System.out.println(System.nanoTime()-time);
System.out.println(System.currentTimeMillis()-timemilis);
}
}
If your predict String is always piped(|) the numbers then you can easily split them using pipe and then keep track of the counts on a HashMap. For example
1234 = 2
1344 = 1
4411 = 5
But if not, then you have to modify the Longest Repeated Substring algorithm. As you need to have all repeated substrings so keep track of all instead of only the Longest one. Also, you have to put a checking for minimum length of substring along with overlapping substring. By searching google you'll find lot of reference of this algorithm.
You seem to need something like an n-gram language model, which is a statistical model that is based on counts of co-occurring events. If you are given some training data, you can derive the probabilities from counts of seen patterns. If not, you can try to specify them manually, but this can get tricky. Once you have such a language model (where the digit patterns correspond to words), you can always predict the next word by picking one with the highest probability given some previous words ("history").
I have a homework assignment to count specific chars in string.
For example: string = "America"
The output should be = a appear 2 times, m appear 1 time, e appear 1 time, r appear 1 time, i appear 1 time and c appear 1 time
public class switchbobo {
/**
* #param args
*/ // TODO Auto-generated method stub
public static void main(String[] args){
String s = "BUNANA";
String lower = s.toLowerCase();
char[] c = lower.toCharArray(); // converting to a char array
int freq =0, freq2 = 0,freq3 = 0,freq4=0,freq5 = 0;
for(int i = 0; i< c.length;i++) {
if(c[i]=='a') // looking for 'a' only
freq++;
if(c[i]=='b')
freq2++;
if (c[i]=='c') {
freq3++;
}
if (c[i]=='d') {
freq4++;
}
}
System.out.println("Total chars "+c.length);
if (freq > 0) {
System.out.println("Number of 'a' are "+freq);
}
}
}
code above is what I have done, but I think it is not make sense to have 26 variables (one for each letter). Do you guys have alternative result?
Obviously your intuition of having a variable for each letter is correct.
The problem is that you don't have any automated way to do the same work on different variables, you don't have any trivial syntax which helps you doing the same work (counting a single char frequency) for 26 different variables.
So what could you do? I'll hint you toward two solutions:
you can use an array (but you will have to find a way to map character a-z to indices 0-25, which is somehow trivial is you reason about ASCII encoding)
you can use a HashMap<Character, Integer> which is an associative container that, in this situation, allows you to have numbers mapped to specific characters so it perfectly fits your needs
You can use HashMap of Character key and Integer value.
HashMap<Character,Integer>
iterate through the string
-if the character exists in the map get the Integer value and increment it.
-if not then insert it to map and set the integer value for 0
This is a pseudo code and you have to try coding it
I am using a HashMap for the solution.
import java.util.*;
public class Sample2 {
/**
* #param args
*/
public static void main(String[] args)
{
HashMap<Character, Integer> map = new HashMap<Character, Integer>();
String test = "BUNANA";
char[] chars = test.toCharArray();
for(int i=0; i<chars.length;i++)
{
if(!map.containsKey(chars[i]))
{
map.put(chars[i], 1);
}
map.put(chars[i], map.get(chars[i])+1);
}
System.out.println(map.toString());
}
}
Produced Output -
{U=2, A=3, B=2, N=3}
In continuation to Jack's answer the following code could be your solution. It uses the an array to store the frequency of characters.
public class SwitchBobo
{
public static void main(String[] args)
{
String s = "BUNANA";
String lower = s.toLowerCase();
char[] c = lower.toCharArray();
int[] freq = new int[26];
for(int i = 0; i< c.length;i++)
{
if(c[i] <= 122)
{
if(c[i] >= 97)
{
freq[(c[i]-97)]++;
}
}
}
System.out.println("Total chars " + c.length);
for(int i = 0; i < 26; i++)
{
if(freq[i] != 0)
System.out.println(((char)(i+97)) + "\t" + freq[i]);
}
}
}
It will give the following output:
Total chars 6
a 2
b 1
n 2
u 1
int a[]=new int[26];//default with count as 0
for each chars at string
if (String having uppercase)
a[chars-'A' ]++
if lowercase
then a[chars-'a']++
public class TestCharCount {
public static void main(String args[]) {
String s = "america";
int len = s.length();
char[] c = s.toCharArray();
int ct = 0;
for (int i = 0; i < len; i++) {
ct = 1;
for (int j = i + 1; j < len; j++) {
if (c[i] == ' ')
break;
if (c[i] == c[j]) {
ct++;
c[j] = ' ';
}
}
if (c[i] != ' ')
System.out.println("number of occurance(s) of " + c[i] + ":"
+ ct);
}
}
}
maybe you can use this
public static int CountInstanceOfChar(String text, char character ) {
char[] listOfChars = text.toCharArray();
int total = 0 ;
for(int charIndex = 0 ; charIndex < listOfChars.length ; charIndex++)
if(listOfChars[charIndex] == character)
total++;
return total;
}
for example:
String text = "america";
char charToFind = 'a';
System.out.println(charToFind +" appear " + CountInstanceOfChar(text,charToFind) +" times");
Count char 'l' in the string.
String test = "Hello";
int count=0;
for(int i=0;i<test.length();i++){
if(test.charAt(i)== 'l'){
count++;
}
}
or
int count= StringUtils.countMatches("Hello", "l");