I am working on a project which involves making a "worker" in java which receives instructions from an input string. In the input string normally should be first four numbers and then afterwards a number and a letter right after being N,S,W, or E. The first 2 numbers in the list are used to determine the size of the area this worker can walk. the next two numbers are the starting point for the worker. The number with the letter determines what direction the worker walks and how many paces. The problem I am having is I don't understand how to get the first four digits out of the string and separate them into what they each should be.
import java.util.*;
import java.io.*;
public class Worker {
private int height;
public void readInstructions(String inputFileName, String outputFileName) throws InvalidWorkerInstructionException{
try{
Scanner in = new Scanner(inputFileName);
PrintWriter wrt;
wrt = new PrintWriter(outputFileName);
if(inputFileName.startsWith("i")){
System.out.println("Input file not found.");
//wrt.println("Input file not found.");
}
while(in.hasNext()){
String s = in.nextLine();
if(Integer.parseInt(s)<= 9){
}
}
}catch(InvalidWorkerInstructionException e){
}catch(FileNotFoundException e){
}
While I would love to ask for a straight up answer, this is a project so I would prefer nobody gives me a fixed code. Please if you can give me advice for what I am doing wrong and where I should be going to solve the problem.
Ok I realized one other thing because I tried the advice given. So I am receiving a string that gives me the name of an input txt. Inside that input txt is the numbers and directions. How can i access this text file? Also how do I determine if it can be opened?
Okay, so you already know how to read the file using a Scanner. All you need to do next is split the String and extract the first four inputs out of it.
Here is the code snippet:
String s = in.nextLine();
int i = 0, digits[] = new int[4];
for(String inp : s.splits(" ")) {
if(i == 4) break;
digits[i++] = Integer.parseInt(inp);
}
Note: I'm assuming that the inputs in your file is space separated. If not then you can replace the space in the split() with the correct delimiter.
If input format is fixed than you can use substring method to get different parts of string. Refer documentation for more detail:
https://docs.oracle.com/javase/7/docs/api/java/lang/String.html#substring(int,%20int)
Example code:
String s = "12345E";
s.substring(0, 2); /* 12 */
s.substring(2, 4); /* 34 */
s.substring(4, 5); /* 5 */
s.substring(5, 6); /* E */
You can use the method .getChars() to accomplish this. Here is what the javadoc says about this method:
public void getChars(int srcBegin,
int srcEnd,
char[] dst,
int dstBegin)
Copies characters from this string into the destination character array.
The first character to be copied is at index srcBegin; the last character to be copied is at index srcEnd-1 (thus the total number of characters to be copied is srcEnd-srcBegin). The characters are copied into the subarray of dst starting at index dstBegin and ending at index:
dstbegin + (srcEnd-srcBegin) - 1
Parameters:
srcBegin - index of the first character in the string to copy.
srcEnd - index after the last character in the string to copy.
dst - the destination array.
dstBegin - the start offset in the destination array.
Throws:
IndexOutOfBoundsException - If any of the following is true:
srcBegin is negative.
srcBegin is greater than srcEnd
srcEnd is greater than the length of this string
dstBegin is negative
dstBegin+(srcEnd-srcBegin) is larger than dst.lengt....
Here is what you could do...
You read in the string - grab its length (You want to make sure that it has all the chars you need)
Read in to a separate array discarding any extraneous chars that are not needed for this functionality..
You can make your own pseudo code to work out the problem once the string is split into an array. Very easy to work with since you know what each location of the array is supposed to do.
This is not a hard problem to solve at all..
Good luck on your project.
Related
This question already has answers here:
Java program to find the character that appears the most number of times in a String?
(8 answers)
Closed 6 years ago.
I got a task from my university today:
Write a program that reads a ( short ) text from the user and prints the so called max letter (most common character in string) , that the letter which the greatest number of occurrences of the given text .
Here it is enough to look at English letters (A- Z) , and not differentiate between uppercase and lowercase letters in the count of the number of occurrences .
For example, if : text = " Ada bada " so should the print show the most common character, this example it would be a.
This is an introductory course, so in this submission we do not need to use the " scanner - class" . We have not gone through this so much.
The program will use the show message input two get the text from user .
Info: The program shall not use while loop ( true / false ) , "return " statement / "break " statement .
I've been struggling with how I can get char values into a table.. am I correct I need to use array to search for most common character? I think I need to use the binarySearch, but that only supports int not char.
I'll be happy for any answers. hint's and solutions. etc.. if you're very kind a full working program, but again please don't use the things I have written down in the "info" section above.
My code:
String text = showInputDialog("Write a short text: ");
//format string to char
String a = text;
char c = a.charAt(4);
/*with this layout it collects number 4 character in the text and print out.
* I could as always go with many char c... but that wouldn't be a clean program * code.. I think I need to make it into a for-loop.. I have only worked with * *for-loops with numbers, not char (letters).. Help? :)
*/
out.print( text + "\n" + c)
//each letter into 1 char, into table
//search for most used letter
Here's the common logic:
split your string into chars
loop over the chars
store the occurrences in a hash, putting the letter as key and occurrences as value
return the highest value in the hash
As how to split string into chars, etc., you can use Google. :)
Here's a similar question.
There's a common program asked to write in schools to calculate the frequency of a letter in a given String. The only thing you gotta do here is find which letter has the maximum frequency. Here's a code that illustrates it:
String s <--- value entered by user
char max_alpha=' '; int max_freq=0, ct=0;
char c;
for(int i=0;i<s.length();i++){
c=s.charAt(i);
if((c>='a'&&c<='z')||(c>='A'&&c<='Z')){
for(int j=0;j<s.length();j++){
if(s.charAt(j)==c)
ct++;
} //for j
}
if(ct>max_freq){
max_freq=ct;
max_alpha=c;
}
ct=0;
s=s.replace(c,'*');
}
System.out.println("Letter appearing maximum times is "+max_alpha);
System.out.println(max_alpha+" appears "+max_freq+" times");
NOTE: This program presumes that all characters in the string are in the same case, i.e., uppercase or lowercase. You can convert the string to a particular case just after getting the input.
I guess this is not a good assigment, if you are unsure about how to start. I wish you for having better teachers!
So you have a text, as:
String text = showInputDialog("Write a short text: ");
The next thing is to have a loop which goes trough each letter of this text, and gets each char of it:
for (int i=0;i<text.length();i++) {
char c=text.charAt(i);
}
Then comes the calculation. The easiest thing is to use a hashMap. I am unsure if this is a good topic for a beginners course, so I guess a more beginner friendly solution would be a better fit.
Make an array of integers - this is the "table" you are referring to.
Each item in the array will correspond to the occurrance of one letter, e.g. histogram[0] will count how many "A", histogram[1] will count how many "B" you have found.
int[] histogram = new int[26]; // assume English alphabet only
for (int i=0;i<histogram.length;i++) {
histogram[i]=0;
}
for (int i=0;i<text.length();i++) {
char c=Character.toUppercase(text.charAt(i));
if ((c>=65) && (c<=90)) {
// it is a letter, histogram[0] contains occurrences of "A", etc.
histogram[c-65]=histogram[c-65]+1;
}
}
Then finally find the biggest occurrence with a for loop...
int candidate=0;
int max=0;
for (int i=0;i<histogram.length;i++) {
if (histogram[i]>max) {
// this has higher occurrence than our previous candidate
max=histogram[i];
candidate=i; // this is the index of char, i.e. 0 if A has the max occurrence
}
}
And print the result:
System.out.println(Character.toString((char)(candidate+65));
Note how messy this all comes as we use ASCII codes, and only letters... Not to mention that this solution does not work at all for non-English texts.
If you have the power of generics and hashmaps, and know some more string functions, this mess can be simplified as:
String text = showInputDialog("Write a short text: ");
Map<Char,Integer> histogram=new HashMap<Char,Integer>();
for (int i=0;i<text.length();i++) {
char c=text.toUppercase().charAt(i));
if (histogram.containsKey(c)) {
// we know this letter, increment its occurrence
int occurrence=histogram.get(c);
histogram.put(c,occurrence+1);
}
else {
// we dunno this letter yet, it is the first occurrence
histogram.put(c,1);
}
}
char candidate=' ';
int max=0;
for (Char c:histogram.keySet()) {
if (histogram.get(c)>max) {
// this has higher occurrence than our previous candidate
max=histogram.get(c);
candidate=c; // this is the char itself
}
}
System.out.println(c);
small print: i didn't run this code but it shall be ok.
Right now I have a program that puts an inputted expression into Postfix Evaluation. Below is a copy of my console.
Enter an expression: ((5*2-1)/6+14/3)*(2*3-5)+7/2
5 2 * 1 - 6 / 14 3 / + 2 3 * 5 - * 7 2 / +
I now need to walk through the output, however this output is just a bunch of System.out.print 's put together. I tried using a stringBuilder however it cant tell the difference between 14 and a 1 and 4.
Is there anyway I can go through each character of this output? I need to put these numbers into a stack.
You can use String.split() and if you need only numbers regular expression.
Here is an Example:
public class Test {
public static void main(String[] args) {
String str = "1 * 2 3 / 4 5 6";
String[] arr = str.split(" ", str.length());
for (int i=0;i < arr.length;i++)
System.out.println(arr[i] + "is diggit? " + arr[i].matches("-?\\d+(\\.\\d+)?"));
}
}
str holds the long String. arr will hold the split sub strings.
you just need to make sure that each sub string differ one space from the other.
Well, you deleted your code while I was reading it, but here's a conceptually developed answer.
As you input every character, you want to push that to the stack.
The unique scenario you've mentioned 14 is unique in that it's two characters.
So what you would want to do is track if the last character was ALSO a number.
Here's a rough pseudo. Your stack should be all Strings to support this.
//unique case for digit
if(s.charAt(0).isDigit()) {
//check to see if the String at the top of a stack is a number by peeking at its first character
if(stack.peek().charAt(0).isDigit()) {
int i = Integer.parseInt(stack.pop()) * 10;
//we want to increment the entire String by 10, so a 1 -> 10
i = i + Character.getNumericValue(s.charAt(0)); //add the last digit, so 10 + 4 = 14
stack.push(Integer.toString(i)); //put the thing back on the stack
}
else {
//handle normally
stack.push(s.substring(0,1));
}
}
Is there a reason you need to parse the actual string?
If so, then what you do is, create a StringBuffer or StringBuilder, and wherever you put System.out.print in your code, append the buffer - including the spaces, which are what will help you differentiate between 1 4 and 14. Then you can convert that to a String. Then you can parse the String by splitting it by the spaces. Then iterate through the resulting String array.
If there is no reason for you to use the actual full string, you can instead use a List object and just add to it in the same places in the code. In this case, you don't need the spaces. Then you'll be able to simply iterate through the list.
You'll still be able to print you output - by printing the elements in the list.
I have a string and I want to use some formulas, in which there is a word that is going to be searched. Sometimes that word could be in different place, depending on the user. In order to make substrings work, I have to ensure that when it happens, the code still works.
String temp = s;//Temp is a long string text
String fehlerspeicher="fehlerspeicher";
if(temp.matches(".*"+fehlerspeicher+".*")){
// i have to find as an integer, how many LETTERS are used till this spesific word
}//to make changes in the following code
String temp1=temp.substring(0, 15000);//15000 is an example. it can be 5000 or 20000 sometimes. It splits the text up from 15000th letter.
String temp2=temp.substring(15000);// It'd be useful to use this integer in these 2 formulas.
temp2=temp2.replaceFirst("200", "20_");
temp=temp1+temp2;
So, could it be somehow implementable? Thanks.
Use indexOf:
public int indexOf(String str)
Returns the index within this string of the first occurrence of the
specified substring.
http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/String.html#indexOf(java.lang.String)
So to get the index of "fehlerspeicher" you can use:
int index = temp.indexOf("fehlerspeicher");
So to get the position of the 'f' in 'fehlerspeicher' you can use:
String temp = "hellofehlerspecher"; //example temp string
int index = temp.indexOf("fehlerspeicher");
int fPos = index + 1; //fpos will equal 6.
I just attempted a programming challenge, which I was not able to successfully complete. The specification is to read 2 lines of input from System.in.
A list of 1-100 space separated words, all of the same length and between 1-10 characters.
A string up to a million characters in length, which contains a permutation of the above list just once. Return the index of where this permutation begins in the string.
For example, we may have:
dog cat rat
abcratdogcattgh
3
Where 3 is the result (as printed by System.out).
It's legal to have a duplicated word in the list:
dog cat rat cat
abccatratdogzzzzdogcatratcat
16
The code that I produced worked providing that the word that the answer begins with has not occurred previously. In the 2nd example here, my code will fail because dog has already appeared before where the answer begins at index 16.
My theory was to:
Find the index where each word occurs in the string
Extract this substring (as we have a number of known words with a known length, this is possible)
Check that all of the words occur in the substring
If they do, return the index that this substring occurs in the original string
Here is my code (it should be compilable):
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class Solution {
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String line = br.readLine();
String[] l = line.split(" ");
String s = br.readLine();
int wl = l[0].length();
int len = wl * l.length;
int sl = s.length();
for (String word : l) {
int i = s.indexOf(word);
int z = i;
//while (i != -1) {
int y = i + len;
if (y <= sl) {
String sub = s.substring(i, y);
if (containsAllWords(l, sub)) {
System.out.println(s.indexOf(sub));
System.exit(0);
}
}
//z+= wl;
//i = s.indexOf(word, z);
//}
}
System.out.println("-1");
}
private static boolean containsAllWords(String[] l, String s) {
String s2 = s;
for (String word : l) {
s2 = s2.replaceFirst(word, "");
}
if (s2.equals(""))
return true;
return false;
}
}
I am able to solve my issue and make it pass the 2nd example by un-commenting the while loop. However this has serious performance implications. When we have an input of 100 words at 10 characters each and a string of 1000000 characters, the time taken to complete is just awful.
Given that each case in the test bench has a maximum execution time, the addition of the while loop would cause the test to fail on the basis of not completing the execution in time.
What would be a better way to approach and solve this problem? I feel defeated.
If you concatenate the strings together and use the new string to search with.
String a = "dog"
String b = "cat"
String c = a+b; //output of c would be "dogcat"
Like this you would overcome the problem of dog appearing somewhere.
But this wouldn't work if catdog is a valid value too.
Here is an approach (pseudo code)
stringArray keys(n) = {"cat", "dog", "rat", "roo", ...};
string bigString(1000000);
L = strlen(keys[0]); // since all are same length
int indices(n, 1000000/L); // much too big - but safe if only one word repeated over and over
for each s in keys
f = -1
do:
f = find s in bigString starting at f+1 // use bigString.indexOf(s, f+1)
write index of f to indices
until no more found
When you are all done, you will have a series of indices (location of first letter of match). Now comes the tricky part. Since the words are all the same length, we're looking for a sequence of indices that are all spaced the same way, in the 10 different "collections". This is a little bit tedious but it should complete in a finite time. Note that it's faster to do it this way than to keep comparing strings (comparing numbers is faster than making sure a complete string is matched, obviously). I would again break it into two parts - first find "any sequence of 10 matches", then "see if this is a unique permutation".
sIndx = sort(indices(:))
dsIndx = diff(sIndx);
sequence = find {n} * 10 in dsIndx
for each s in sequence
check if unique permutation
I hope this gets you going.
Perhaps not the best optimized version, but how about following theory to give you some ideas:
Count length of all words in row.
Take random word from list and find the starting index of its first
occurence.
Take a substring with length counted above before and after that
index (e.g. if index is 15 and 3 words of 4 letters long, take
substring from 15-8 to 15+11).
Make a copy of the word list with earlier random word removed.
Check the appending/prepending [word_length] letters to see if they
match a new word on the list.
If word matches copy of list, remove it from copy of list and move further
If all words found, break loop.
If not all words found, find starting index of next occurence of
earlier random word and go back to 3.
Why it would help:
Which word you pick to begin with wouldn't matter, since every word
needs to be in the succcessful match anyway.
You don't have to manually loop through a lot of the characters,
unless there are lots of near complete false matches.
As a supposed match keeps growing, you have less words on the list copy left to compare to.
Can also keep track or furthest index you've gone to, so you can
sometimes limit the backwards length of picked substring (as it
cannot overlap to where you've already been, if the occurence are
closeby to each other).
So I am trying to solve the problem 1772 of the Caribbean online judge web page http://coj.uci.cu/24h/problem.xhtml?abb=1772, the problem asks to find if a substring of a bigger string contains at least one palindrome inside it:
e.g. Analyzing the sub-strings taken from the following string: "baraabarbabartaarabcde"
"bara" contains a palindrome "ara"
"abar" contains a palindrome "aba"
"babar" contains a palindrome "babar"
"taar" contains a palindrome "aa"
"abcde" does not contains any palindrome.
etc etc etc...
I believe my approach is really fast because I am iterating the strings starting at the first char and at the last char at the same time, advancing towards the center of the string looking only for the following patterns: "aa" "aba" whenever I find a pattern like those I can say the substring given contains a palindrome inside it. Now the problem is that the algorithm is taking a long time but I can't spot the problem on it. Please help me find it I am really lost on this one. Here is my algorithm
public static boolean hasPalindromeInside(String str)
{
int midpoint=(int) Math.ceil((float)str.length()/2.0);
int k = str.length()-1;
for(int i = 0; i < midpoint;i++)
{
char letterLeft = str.charAt(i);
char secondLetterLeft=str.charAt(i+1);
char letterRight = str.charAt(k);
char secondLetterRight = str.charAt(k-1);
if((i+2)<str.length())
{
char thirdLetterLeft=str.charAt(i+2);
char thirdLetterRight=str.charAt(k-2);
if(letterLeft == thirdLetterLeft || letterRight == thirdLetterRight)
{
return true;
}
}
if(letterLeft == secondLetterLeft || letterRight==secondLetterRight)
{
return true;
}
k--;
}
return false;
}
}
I have removed the code that grabs the input strings and intervals of sub-strings, I am using String.substring() to get the substrings and I don't think that will be causing the problem. If you need that code please let me know.
Thanks!
I think you can solve this in O(1) time per query given O(n) preprocessing to find the locations of all 2 and 3 character palindromes. (Any even plaindrome will have a 2 character plaindrome at the centre, while any odd will have a 3 character one so it suffices to check 2 and 3.)
For example,
Given your string baraabarbabartaarabcde, first compute an array indicating the locations of the 2 character palindromes:
baraabarbabartaarabcde
000100000000001000000-
Then compute the cumulative sum of this array:
baraabarbabartaarabcde
000100000000001000000-
000111111111112222222-
By doing a subtraction you can immediately work out whether there are any 2 character palindromes in a query range.
Similarly for three character plaindromes:
baraabarbabartaarabcde String
01001000100000010000-- Indicator
01112222333333344444-- Cumulative