I'm very new to stack overflow, and I've been learning Java for a few months now. I have so far created a calculator which can find multiple sets of brackets and correctly work them out. However I'm struggling to figure out how to get it to correctly find brackets inside of brackets correctly.
For example;
Say I input the below string...
"10+(2+(3*2))"
I basically want it to set "3*2" to another string. How would I go about getting whats inside the deepest brackets?
Thanks in advance for any help/advice, ask questions if I've been unclear or too vague.
Here is what I have so far for checking for brackets;
public static String checkForBrackets(String formula) {
for (int i = 0; i < formulaChars.size(); i++) {
for (int j = 0; j < formulaChars.size(); j++) {
if ((formulaChars.get(i) == ')') && (formulaChars.get(j) == '(')) {
bracketFormula = formula.substring(j + 1, i);
formulaChars.clear();
}
}
}
System.out.println(bracketFormula)
}
The for loops are checking for the left most opening and closing bracket.
If I was to input the string "10+(2+(3*2))", the code would return "2+(3*2" instead of what I want; "3*2"
Related
I need help checking rows, columns, and boxes for a Sudoku program. I am a high school student that needs help completing this project. If any one could provide help that would be awesome! I am currently working on checking boxes where I have a comment saying "Start Here". Thanks!
import java.util.*;
public class Run
{
Scanner scanner = new Scanner(System.in);
public static void main(String[] args)
{
char [][] board = new char [9][9];
Scanner scanner = new Scanner(System.in);
System.out.println("Welcome to Sudoku!\n");
fill(board);
printBoard(board);
inputLengthandDigits(board);
System.out.println();
printBoard(board);
}
public static void fill(char[][] arr){
for(int row = 0; row < arr.length; row++){
for(int col= 0; col< arr[row].length; col++){
arr[row][col] = '-';
}
}
}
public static void printBoard(char [][] array)
{
for(char[] row: array)
{
for(char play: row)
{
System.out.print(play+ " ");
}
System.out.println();
}
}
public static void inputLengthandDigits(char[][] array){
Scanner in = new Scanner(System.in);
for (int i = 0; i < 9; i++)
{
System.out.println("\nEnter the numbers in row " + (i+1) + ":");
String input = in.nextLine();
String numbers = "123456789-";
boolean numberscheck = false;
boolean endCheck = true;
boolean onlyOnce = true;
//Input Validation Starts Here!
//Checks if Input is only digits 0-9
do{
if(endCheck==false){
System.out.println("\nPlease input numbers only (1-9)!");
input = in.nextLine();
}
if(onlyOnce==false){
System.out.println("\nPlease input numbers only once!");
input = in.nextLine();
}
//Checks Length of User Input
while(input.length() < 9 || input.length() > 9){
System.out.println("\nPlease input 9 numbers!");
input = in.nextLine();
}
//Start Here
for(int a = 0; a<input.length()-1; a++){
for(int b= a + 1; b<input.length(); b++){
if(input.charAt(a)==input.charAt(b)){
onlyOnce = false;
}
}
}
for(int x = 0; x < input.length(); x++){
char thing = input.charAt(x);
numberscheck = false;
for(int y = 0; y < numbers.length(); y++){
char numbersn = numbers.charAt(y);
if(thing == numbersn){
numberscheck = true;
endCheck = true;
break;
}
}
if(numberscheck == false){
endCheck = false;
break;
}
}
}while(endCheck==false || onlyOnce==false);
for(int j=0; j<9; j++){
array[i][j] = input.charAt(j);
}
}
}
}
My initial response is too long for a comment. I'm not sure I have a solution to your problem, largely because you haven't actually pointed out which bit is a problem yet, but these pointers should help improve things anyway:
Please reformat your code. It is actually quite painful to look at. Spaces should be used consistently around variables, key words, brackets and operands. Opening curly braces should be on the same line as the method signature, for() loop or whatever else comes first. You have random blank lines within methods which don't separate logical sections so are just confusing. The compiler won't care about any of this, but if you can make your code look neater people will instinctively presume you care and are more likely to credit you with the ability to write decent code.
You have declared a new scanner variable three times. This is redundant and wasteful clutter. Either have a single, class-wide scanner, or (preferably), only create a scanner in a method which actually uses it and then remember to call scanner.close() once the scanner is no longer required.
inputLengthandDigits is a weird name. Is 'Lengthand' a single word, or should it be 'inputLengtHandDigits' or 'inputLengthAndDigits'? In camel case, capitalise every word except the first to make the whole easier to read. Whatever it should be, I don't understand from the name what this method does. It isn't inputting anything, it's getting inputs from someone else. Perhaps getData or populateGrid might be more explanatory.
9 appears quite a few times, with no explanation. I know where it came from, because I spend far too much time playing Sudoku, but it is a magic number and these are to be avoided at all costs. I met a magic number in the workplace once, wasted half a day trying to do what could have been a ten minute job if colleagues had recorded what the number was and where it came from. Here, just have a private static final int maxNumber = 9; statement.
A good thing: your main() method has almost no fiddly details in it. You have effectively used method calls to tell a story and describe what is happening elsewhere. This is a really, really good thing to do :)
Some of your logic tests can be tidied up a bit, e.g. !onlyOnce is the same as onlyOnce == false, and input.length() < maxNumber || input.length() > maxNumber can be simplified to input.length() != maxNumber. It's exactly the same logic, but faster to type and easier to read :)
It looks like your code under the //Start here comment is checking that you don't have any duplicate numbers. If you do get duplicate numbers, the program is still going to try and run the next bit of code before asking the user for alternative input. Is that something you want to happen, or a waste of time?
I actually burst out laughing when I saw a variable called 'thing'. Please, find a name which actually describes the purpose of this variable.
I have now run the code, and it rightly pointed out an error when I tried to key in duplicate numbers for row 4. However, it's now stuck there and keeps asking me to try again even when I put in a valid set of digits. This needs to be fixed. Look closely at which flags are triggering the request to retry. Run your code in debugging mode (you are using an IDE like IntelliJ or Eclipse, aren't you?) and deliberately enter a bad row to see the behaviour for yourself and where the logic is going wrong.
This whole method to get the row input, validate it, and then populate the array, is very big and confusing. You need to refactor it into a lot of smaller methods. Here is a suggestion to play with:
private static char[][] populateGrid(char[][] array) {
Scanner scanner = new Scanner(System.in);
for (int i = 0; i <maxNumber; i++) {
String rowData = getRowInput(scanner);
populateRow(array, rowNumber, rowData);
}
scanner.close;
return array;
}
private static String getRowInput(Scanner scanner) {
System.out.println("\nEnter the numbers in row " + (i + 1) + ":");
String input = scanner.nextLine();
while (!isValidInput(input) {
System.out.println("Please enter only the digits 1-9 in any order, with no duplicates or omissions");
input = scanner.nextLine();
}
return input;
}
private static boolean isValidInput(String input) {
if (!rightLengthOfInput(input)) {
return false;
}
if (!allUniqueDigits(input)) {
return false;
}
if (!usesCorrectCharacters(input)) {
return false;
}
return true;
}
I'll leave you to make the different input validation methods. It will largely be a case of moving your existing code, but the method names will help humans understand what each section is doing. This structure also allows you to cleanly add more validation checks, should such a thing be desired in the future.
Things to consider after all that:
Are you going to check that you have a viable Sudoku solution, or will you trust the user to put in correct data such that the columns also have each of the nine digits in them? How will you handle an invalid grid, e.g. each row is identical?
How far does this assignment want you to go? Do you need to systematically remove numbers to get a solvable puzzle rather than a completed grid? Will the assignment stop at a puzzle which can be seen in the console, or do you need a printable format, or will the user be able to play through the program? If the latter option, will this be in the console or using a graphical interface?
I appreciate that there is a lot to think about and work on here. Take it steadily, one step at a time, and keep asking questions if you need too.
I need to create a loop that adds "o" after each consonant
I am going to walk you through what I corrected and changed in your code to make it work in order to make it quick and easy for you to comprehend why your code doesn't work and why my answer fixes it.
The mistakes you made are basic ones and frankly you shouldn't have to much of a hard time correcting them yourself if you would use a debugger that walks you step by step in how your code works. You should look on how to use a debugger (for example the debugger used in Eclipse, hopefully you are using an IDE to make your life easier).
Firstly, when you are looking for a consonant in your code, you are only walking through the half of it because of your condition for(int x = 0; x<20; x++) since your string holding the consonants if of a length of 40 characters. This means you are missing consonants like the letter s.
Then you are correctly the consonants you find according to your Swedish language game. But you are never handling characters that are not of these found consonants. You should make a case where you handle these "non consonant" letters, may they be vowels or any kind of character (like punctuation marks and so on). I am fixing this with the use of a simple boolean here.
Keep in mind that my goal here is to change your code as little as I can, thus I went for adding a boolean to handle your cases (checking the presence of a consonant). There are, obviously, many other ways to implement what you are trying to do.
Here come the changes you should add to your code:
/*This comes after your print "På rövarspråk:"*/
boolean isConsonant = false; //Boolean to check wether there is a consonant or not
for(int i = 0; i<length; i++) {
//You didn't go through the whole consonants list you made with your prevision condition
for(int x = 0; x<consonants.length; x++){
if(array[i] == consonants[x])
{
isConsonant = true; //Set the boolean accordingly
String add = array[i]+"o"+array[i];
slang = slang + add;
break;
}
}
if(!isConsonant){ //If we don't have a consonant, add the char to the result string
slang += array[i];
}
isConsonant = false; //Reset the boolean for the next character
}
/*Here you can print the result (slang) if you want, as you did*/
so the idea is to dublicate consonants and put "o" between them, like t becomes tot, s becomes sos. Vocals are just copied. So you need a method that tells you if a given character is a vocal or consonant to base your decision on that.
public static boolean isConsonant(char inputChar){
final String consonantsx = "bBcCdDfFgGhHjJkKlLmMnNpPqQrRsStTvVwWxXzZ";
char consonants[] = consonantsx.toCharArray(); // String to charr
for(int i=0; i < consonants.length;i++){
if(inputChar == consonants[i]){ //note that in Strings u use the equals method instead of "=="
return true;
}
}
return false;
}
Given this method you can use it in the "translator method".
public String rovarSpraket(String normalString) {
char[] array = normalString.toCharArray(); // Input to a char array
System.out.println("På rövarspråk:");
String slang = "";
for (int i = 0; i < normalString.length(); i++) {
String add = "" + array[i];
if(Goran.isConsonant(array[i])){
add += "o" + array[i];
}
slang += add;
}
return slang;
}
This translates stubborn to sostotubobboborornon like in the wikipedia article https://en.wikipedia.org/wiki/R%C3%B6varspr%C3%A5ket.
This is what the program should do:
The word, zatabracabrac, is not square free, since it has subword, abrac twice start-
ing at position 4 of the word.
We are not allowed to use strings, breaks or other complex stuff. I get the square and square not part but am unable to find its place. I think I went wrong some place like I can't figure it out.
public static void main(String[] args) {
// part (a) of the main
Scanner keyboard = new Scanner(System.in);
System.out.println("***************************");
System.out.println(" Part (a)");
System.out.println("***************************");
do{
System.out.println("Enter a word and then press enter:");
String str=keyboard.next();
char[] word = str.toCharArray();
isSquareFree(word);
System.out.println("Do you want to test another word? Press y for yes, or another key for no");
}while(keyboard.next().charAt(0)=='y');
public static void isSquareFree(char[] word){
int z = 0;
for(int i=0; i<word.length; i++){
for(int j=0; j<word.length-1;j++){
if (word[j] == word[j+1]){
z = 1;
j = word.length;
}
else{
z = 2;
}
}
}
if (z == 1){
System.out.println();
System.out.println("Not Square Free");
}
else{
System.out.println();
System.out.println("Square Free");
}
}
}
Downvotes on the question: this is not where you solve your homework... we all went through having homeworks and solved them (well, most of us), and that's partly why we're capable of helping you.
You're checking whether the word contains two consecutive characters which are the same.
That's not what you want, try another solution.
Here's why it does what I said above:
The outer for loop doesn't have an effect on the inner one, since i is not used inside
Index j and j+1 in the same iteration as a character and the next one
Other notes:
j = word.length is the same as break here, try using that, it stops your loop like the end condition was satisfied; read more: http://docs.oracle.com/javase/tutorial/java/nutsandbolts/branch.html
For easier testing, you might want to use another main function containing only calls like isSquareFree("zatabracabrac".toCharArray());, even multiple ones to see multiple test results at once
This will greatly reduce the change-compile-run-check cycle's length.
You can use a debugger in an IDE (Eclipse or IntelliJ) to see what your program does.
Without debugging you can use println/print/printf calls to see how many iterations you have and what your values during those iterations.
Hints on solution:
As I see you're essentially looking for consecutive k-length subword duplicates
You phrased it right in the comment, the arbitrary length is giving it another level
At each position i try to look for a subword with length k which has a corresponding match starting at i + k (this helps the consecutive constraint)
k can be anything between a letter and half of the string (more than that is overkill since it cannot repeat twice)
I didn't code it, but it would be my first try
In your examples:
borborygmus
^=>
i
borborygmus
^=>
i+k
With k = 3 there is a match
zatabracabrac
^===>
i
zatabracabrac
^===>
i+k
With k = 5 there is a match
I know there is an easier way of making things work to check whether a string is a palindrome or not, but I wanted to try it using library functions and I came up with the code below.
public boolean isPalindrome1(String input)
{
int length = input.length()/2;
if(input.length()%2!=0)
{
length = length + 1;
}
return(input.substring(0,length).equals(new StringBuilder(input.substring(length, input.length())).reverse().toString()));
}
I'm trying to check whether half the string is equal to the other half's reverse. But it is getting messed up for odd and even lengths. Can someone point corrections in this where it will work for odd, even lengths as well as empty string and string of length = 1.
You're already using reverse(). Why can you not compare the input String with the reverse? Isn't that exactly what you're wanting in the first place? No need to be splitting things in half in a complicated way.
you can:
return new StringBuilder(input).reverse().toString().equals(input);
here you go as you want to know :
public boolean isPalindrome(String input) {
for (int i = 0; i < input.length() / 2; i++) {
if (input.charAt(i) != input.charAt(input.length() - 1 - i)) {
return false;
}
}
return true;
}
Hey guys, I'm new to Java (well, 3/4 of a year spent on it).
So I don't know much about it, I can do basic things, but the advanced concepts have not been explained to me, and there is so much to learn! So please go a little but easy on me...
Ok, so I have this project where I need to read lines of text from a file into an array but only those which meet specific conditions. Now, I read the lines into the array, and then skip out on all of those which don't meet the criteria. I use a for loop for this. This is fine, but then when I print out my array (required) null values crop up all over the place where I skipped out on the words.
How would I remove the null elements specifically? I have tried looking everywhere, but the explanations have gone way over my head!
Here is the code that I have to deal with the arrays specifically: (scanf is the scanner, created a few lines ago):
//create string array and re-open file
scanf = new Scanner(new File ("3letterWords.txt"));//re-open file
String words [] = new String [countLines];//word array
String read = "";//to read file
int consonant=0;//count consonants
int vowel=0;//count vowels
//scan words into array
for (int i=0; i<countLines; i++)
{
read=scanf.nextLine();
if (read.length()!=0)//skip blank lines
{
//add vowels
if (read.charAt(0)=='a'||read.charAt(0)=='e'||read.charAt(0)=='i'||read.charAt(0)=='o'||read.charAt(0)=='u')
{
if (read.charAt(2)=='a'||read.charAt(2)=='e'||read.charAt(2)=='i'||read.charAt(2)=='o'||read.charAt(2)=='u')
{
words[i]=read;
vowel++;
}
}
//add consonants
if (read.charAt(0)!='a'&&read.charAt(0)!='e'&&read.charAt(0)!='i'&&read.charAt(0)!='o'&&read.charAt(0)!='u')
{
if (read.charAt(2)!='a'&&read.charAt(2)!='e'&&read.charAt(2)!='i'&&read.charAt(2)!='o'&&read.charAt(2)!='u')
{
words[i]=read;
consonant++;
}
}
}//end if
//break out of loop when reached EOF
if (scanf.hasNext()==false)
break;
}//end for
//print data
System.out.println("There are "+vowel+" vowel words\nThere are "+consonant+" consonant words\nList of words: ");
for (int i=0; i<words.length; i++)
System.out.println(words[i]);
Thanks so much for any help received!
Just have a different counter for the words array and increment it only when you add a word:
int count = 0;
for (int i=0; i<countLines; i++) {
...
// in place of: words[i] = read;
words[count++] = read;
...
}
When printing the words, just loop from 0 to count.
Also, here's a simpler way of checking for a vowel/consonant. Instead of:
if (read.charAt(0)=='a'||read.charAt(0)=='e'||read.charAt(0)=='i'||read.charAt(0)=='o'||read.charAt(0)=='u')
you can do:
if ("aeiou".indexOf(read.charAt(0)) > -1)
Update: Say read.charAt(0) is some character x. The above line says look for that character in the string "aeiou". indexOf returns the position of the character if found or -1 otherwise. So anything > -1 means that x was one of the characters in "aeiou", in other words, x is a vowel.
public static String[] removeElements(String[] allElements) {
String[] _localAllElements = new String[allElements.length];
for(int i = 0; i < allElements.length; i++)
if(allElements[i] != null)
_localAllElements[i] = allElements[i];
return _localAllElements;
}