I've just started to learn Java,and I've got some questions for my code. Well,the task is to get a number and print a matrix like this:
get 3,and print:
1 2 3
8 9 4
7 6 5
get 4,and print:
1 2 3 4
12 13 14 5
11 16 15 6
10 9 8 7
Because I'm learning algorithm,so I deal the question by DFS, here's my cpp code,which can solve the task.
#include "iostream"
using namespace std;
int n;
int matrix[100][100]={0};
int visited[100][100]={0};
void dfs(int n,int x,int y,int i,int dire)
{
//x,y is the coordinate,i is the number to write
//dire is the variety to control the direction of the dfs
if(i==n*n+1)return;
switch(dire)
{
case(1)://write the number on right
{
if(visited[x][y+1]==0&&y+1<n)
{
visited[x][y+1]=1;
matrix[x][y+1]=i;
i++;
dfs(n,x,y+1,i,1);
}
else dfs(n,x,y,i,2);
break;
}
case(2)://down
{
if(visited[x+1][y]==0&&x+1<n)
{
visited[x+1][y]=1;
matrix[x+1][y]=i;
i++;
dfs(n,x+1,y,i,2);
}
else dfs(n,x,y,i,3);
break;
}
case(3)://left
{
if(visited[x][y-1]==0&&y-1>=0)
{
visited[x][y-1]=1;
matrix[x][y-1]=i;
i++;
dfs(n,x,y-1,i,3);
}
else dfs(n,x,y,i,4);
break;
}
case(4)://up
{
if(visited[x-1][y]==0&&x-1>=0)
{
visited[x-1][y]=1;
matrix[x-1][y]=i;
i++;
dfs(n,x-1,y,i,4);
}
else dfs(n,x,y,i,1);
break;
}
}
}
void output(int n)
{
int p,q=0;
for(q=0;q<n;q++)
{
for(p=0;p<n;p++)
{
cout<<matrix[q][p]<<" ";
if(matrix[q][p]<10)
cout<<" ";
if(matrix[q][p]<100)
cout<<" ";
}
cout<<endl;
}
}
int main()
{
cin>>n;
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
matrix[i][j]=0;
visited[i][j]=0;
}
}
///dfs_r(n,0,-1,1);
dfs(n,0,-1,1,1);
output(n);
}
But things goes wrong when I translate it into Java
import java.util.Scanner;
public class mainclass{
public static class method{
int n;
int visited[][]=new int[n][n];
int matrix[][]=new int[n][n];
method(int temp){
n=temp;
}
void dfs(int x,int y,int i,int dire)
{
if(i==n*n+1)return;
switch(dire)
{
case(1):
{
if(visited[x][y+1]==0&&y+1<n)
{
visited[x][y+1]=1;
matrix[x][y+1]=i;
i++;
dfs(x,y+1,i,1);
}
else dfs(x,y,i,2);
break;
}
case(2):
{
if(visited[x+1][y]==0&&x+1<n)
{
visited[x+1][y]=1;
matrix[x+1][y]=i;
i++;
dfs(x+1,y,i,2);
}
else dfs(x,y,i,3);
break;
}
case(3):
{
if(visited[x][y-1]==0&&y-1>=0)
{
visited[x][y-1]=1;
matrix[x][y-1]=i;
i++;
dfs(x,y-1,i,3);
}
else dfs(x,y,i,4);
break;
}
case(4):
{
if(visited[x-1][y]==0&&x-1>=0)
{
visited[x-1][y]=1;
matrix[x-1][y]=i;
i++;
dfs(x-1,y,i,4);
}
else dfs(x,y,i,1);
break;
}
}
}
void output()
{
int p,q=0;
for(q=0;q<n;q++)
{
for(p=0;p<n;p++)
{
System.out.print(matrix[q][p]);
if(matrix[q][p]<10)
System.out.print(" ");
if(matrix[q][p]<100)
System.out.print(" ");
}
System.out.println();
}
}
}
public static void main(String args[]){
Scanner reader=new Scanner(System.in);
int n=reader.nextInt();
method c=new method(n);
c.dfs(0,-1,1,1);
c.output();
}
}
I think my algorithm is all right,but I can't work it out why my Java code crashes. I think I should learn more about basic grammar of Java.
edit:
I use dev-cpp to run my cpp code and eclipse to run my Java code. I'm not really know how to describe how does the crash of my Eclipse got, the code is:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0
at mainclass$method.dfs(mainclass.java:17)
at mainclass.main(mainclass.java:87)
<terminated, exit value: 1>C:\Program Files\Java\jre1.8.0_101\bin\javaw.exe (2016年9月27日 上午9:51:32)
the crash scene
(The answer there supposes you have an IDE, like Eclipse).
The really, really dirty way
You can, when in doubt, always rely on a good old System.out.println(yourobject). Be careful about objects, never forget that you can turn them into String and check inner objets (in your case, visited[1][2] or matrix[2][0] for example). BUT it sucks. Really. It might suffice for your needs, but it is really a bad habit to take.
The 'okay' way (EDIT)
Use a tool named SLF4J to get some additional traces. As you are only on a small method and not a complete project, I would not command you to deploy this tool yet, but keep in mind that it is a good way to both figure out what happens and have your console logging what you need, especially when the projects are getting intersting (read: bigger).
The good and elegant way
Learn a bit about a tool called debug mode. You can find further help on the Eclipse help center, but basically the steps are:
Place a breakpoint. On the left of your code (with line numbers), you can right-click to toogle / enable / disable breakpoints.
Run your program in debug. It is a little bug (how convenient) near the classic run icon. You'll get redirected to the debug perspective.
The run will be interrupted where you toogled your breakpoint. There, you will be able to go, step by step, into your code. You will also be able to check the state of every variable you declared, in order to identify your problem.
[Your job here is to make the necessary changes]
Now you know about debugger, ArrayOutOfBoundsException and became a better person in general thanks to this good practice.
Vogella has a good tutorial about how to use the debugger in a nice way. Learn to use it if you plan on keeping on Java, because this will save you a lot of time (an awful lot, believe me).
Related
Im a beginner.
Here is a binary search code.Its showing array out of bounds error for main method.
please look into the program and kindly tell me my mistake.ill be grateful for ur service.
i have to write all this crap cause i cant post it as its asking for more details.
public class BinaryS
{
int n;
public BinaryS(int z)
{
n=z;
}
static int pos;
static boolean flag=false;
public void disp()
{
int arr[]={0,1,2,3,4};
int len=arr.length;
int first=0;
int last=len;
int mid=(int)(first+last/2);
//boolean flag=false;
while(mid>=0 && mid<=len)
{
if(n<arr[mid])
{
last=mid;
}
if(n>arr[mid])
{
first=mid;
}
if(n==arr[mid])
{
flag=true;
pos=mid+1;
}
}
if(flag==true){
System.out.println("the no."+n+"is found at"+pos);
}
else{
System.out.println("the no."+n+"is not found ");
}
}
public static void main(String args[])
{
BinaryS obj=new BinaryS(2);
obj.disp();
}
}
Currently your code does compile, and runs forever - because of this loop:
while(mid>=0 && mid<=len)
{
// Code which doesn't modify mid or len
}
Assuming it gets into that loop at all (which it does), the condition is never going to become false - so unless you return or break from within the loop (you don't) or an exception is thrown (it isn't) you're just going to keep going round the loop.
This is where you should:
Use a debugger to observe what's happening
Think about what the condition should actually be and how you want it to become false
Adjust your code to either change the condition, or change the loop body so that it modifies mid or len
Hi I'm currently working on getting my Quick Sort program working but cannot figure out where I'm going wrong, i have spent hours trying to find out why it's not working but no luck,when I run my code nothing happens. I have four other sorting algorithms working in a similar fashion which is what's confusing me the most.
Below is my code for the Quick Sort program
import java.io.IOException;
public class QuickSort {
public static int[] compute(int[] array, int lower, int higher )throws IOException{
if(lower<higher){
int pivot=split(array,lower,higher);
if(pivot>1)
compute(array, lower, pivot-1);
if(pivot+1<higher)
compute(array, pivot+1, higher);
}
return array;
}
public static int split(int[] array, int lower, int higher){
while(true){
int pivot=array[lower];
while(array[lower]<pivot)
lower++;
while(array[higher]>pivot)
higher--;
if(lower<higher){
int temp=array[higher];
array[higher]=array[lower];
array[lower]=temp;
}
else{
return higher;
}
}
}
}
Here is my Test class that's running the code:
import java.io.IOException;
import java.util.Scanner;
public class Test extends ReadIn{
static BubbleSort bubble=new BubbleSort();
public static void main(String[] args) throws IOException{
System.out.println("Enter 1 for BubbleSort\nEnter 2 for Insertion Sort\nEnter 3 for Selection Sort\nEnter 4 for Merge Sort\nEnter 5 for QuickSort\nPlease input sorting algorithm to use for sorting:");
Scanner input=new Scanner(System.in);
int number=input.nextInt();
final long startTime = System.currentTimeMillis();
int[] Array=read();
if(number==1){
Array=BubbleSort.compute(Array);
for(int i=0;i<BubbleSort.compute(Array).length;i++){
System.out.println(Array[i]);
}
}
if(number==2){
Array=InsertionSort.compute(Array);
for(int i=0;i<InsertionSort.compute(Array).length;i++){
System.out.println(Array[i]);
}
}
if(number==3){
Array=SelectionSort.compute(Array);
for(int i=0;i<SelectionSort.compute(Array).length;i++){
System.out.println(Array[i]);
}
}
if(number==4){
Array=MergeSort.compute(Array);
for(int i=0;i<MergeSort.compute(Array).length;i++){
System.out.println(Array[i]);
}
}
if(number==5){
Array=QuickSort.compute(Array,0,Array.length-1);
for(int i=0;i<QuickSort.compute(Array,0,Array.length-1).length;i++){
System.out.print(Array[i]);
}
}
final long endTime = System.currentTimeMillis();
System.out.println("Total execution time: " + (endTime - startTime) );
}
}
When I press 5 nothing happens, the rest work perfectly.
I cant figure out whatsoever what the problem is so any help or input would be appreciated.
Your Quicksort code loops forever if there's duplicate numbers in the input, since the numbers can just keep swapping with each other. As mentioned in the comment, you should manually try out your code with a sample array, or check the code running with a debugger. See the example array below.
You might want to switch the while(true) loop to a recursive call to make the code a little clearer. Also, you can practice going through the different steps of Quicksort on my Quicksort online tutorial.
Say the array = {3,1,2,3} and the pivot is 3. Nothing will change and the code will loop forever.
while(true){
int pivot=array[lower];
while(array[lower]<pivot)
lower++;
while(array[higher]>pivot)
higher--;
if(lower<higher){ //this will just swap the 3's with each other.
int temp=array[higher];
array[higher]=array[lower];
array[lower]=temp;
}
else{
return higher;
}
}
While it looks like your program is doing nothing, it probably just loops infinitely inside this loop:
while(true){
int pivot=array[lower];
while(array[lower]<pivot)
lower++;
while(array[higher]>pivot)
higher--;
if(lower<higher){
int temp=array[higher];
array[higher]=array[lower];
array[lower]=temp;
// I recommend adding this line for you to see what's going on
System.out.println("lower="+lower+", higher="+higher+", pivot="+pivot);
}
else{
return higher;
}
}
for example, if you have equal values in your Array, say value 65 is there twice, that loop will run forever...
int[] Array={1,41,2,90,32,65,12,43,78,65,46,67};
Also, in your loop above I added and extra printout of higher, lower, and pivot values - it will help you see what is happening inside that devious loop.
In general writing a while(true) loop is not a good practice, because it's so easy to hang your system on it.
I know how to calculate easy expression without variables. But how to do, when in line we have expression with "x"?
For example
(x+1)*(x-1)
In this example program should to return: x^2 - 1
It's a non-trivial endeavor. I would strongly suggest you look at what's out there. For example Symja
You might want to look at the scripting feature of java. It seems that you can execute Javascript (or other scripting languages) from Java using this scripting engine.
You will find some examples at https://today.java.net/pub/a/today/2006/04/11/scripting-for-java-platform.html.
What you are asking for, is letting a program transform (and possibly solve) mathematical equations. This is of course possible and there are tools and certainly APIs around which do it, but it's definitely beyond hacking a java program by your own.
In case you just like to calculate the result of a given formula, then this is doable. Interestingly, you can just throw an equation at Google (e.g. (5 + 3) * (8-4)) and it will give you the result. So, why not just use it? ;-)
When we go to the interview they asking the this logical type of question. i to met the same problem. but i couldn't able to success the interview because this type of questions. Later i found the result of my own after i search in in the internet. Friends who are all want to do this..
follow this operation. i will give this full of free.
I will enter the equation as string Like.
a*b*c+d/m-x.
get this equation as string object. and use following functions.#
public void calc() throws IOException
{
String equation,store,get;
StringBuilder sb= new StringBuilder();
DataInputStream dis= new DataInputStream(System.in);
System.out.println("Enter the equation");
equation= dis.readLine();
equation="%"+equation+"%";
byte[] buf= equation.getBytes();
for(int i=0;i<equation.length();i++)
{
if(buf[i]>=97&&buf[i]<=122)
{
System.out.println("Enter the value for "+(char)buf[i]);
get=dis.readLine();
sb.append(get);
}
else
sb.append((char)buf[i]);
}
store= sb.toString();
char[] buf1= new char[25];
for(int i=0;i<store.length();i++)
{
buf1[i]=store.charAt(i);
}
for(int i=0;i<buf1.length;i++)
{
no.append(buf1[i]);
}
System.out.println(no.toString());
int m,n=0;
for(int i=0;i<no.length()-1;i++)
{
if('/'==no.charAt(i))
{
leftCount=rightCount=0;
m=findLeftValue(i-1) / findRightValue(i+1);
no.replace(i-leftCount, i+rightCount+1, String.valueOf(m));
i=0;
}
}
for(int i=0;i<no.length()-1;i++)
{
if('*'==no.charAt(i))
{
leftCount=rightCount=0;
m=findLeftValue(i-1) * findRightValue(i+1);
no.replace(i-leftCount, i+rightCount+1, String.valueOf(m));
i=0;
}
}
for(int i=0;i<no.length()-1;i++)
{
if('+'==no.charAt(i))
{
leftCount=rightCount=0;
m=findLeftValue(i-1) + findRightValue(i+1);
no.replace(i-leftCount, i+rightCount+1, String.valueOf(m));
i=0;
}
}
for(int i=0;i<no.length()-1;i++)
{
if('-'==no.charAt(i))
{
leftCount=rightCount=0;
m=findLeftValue(i-1) - findRightValue(i+1);
no.replace(i-leftCount, i+rightCount+1, String.valueOf(m));
i=0;
}
}
for(int i=0;i<no.length();i++)
{
if('%'==no.charAt(i))
{
no.deleteCharAt(i);
i=0;
}
}
System.out.println(no.toString());
}
public int findLeftValue(int i)
{
StringBuilder sb= new StringBuilder();
int x=0;
while(no.charAt(i)!='*'&&no.charAt(i)!='+'&&no.charAt(i)!='-'&&no.charAt(i)!='/' &&no.charAt(i)!='%')
{
leftCount++;
sb.insert(0, no.charAt(i));
i--;
}
x=Integer.parseInt(sb.toString());
return x;
}
public int findRightValue(int i)
{
StringBuilder sb= new StringBuilder();
int x;
while(no.charAt(i)!='*'&&no.charAt(i)!='+'&&no.charAt(i)!='-'&&no.charAt(i)!='/' &&no.charAt(i)!='%')
{
rightCount++;
sb.append(no.charAt(i));
i++;
}
x=Integer.parseInt(sb.toString());
return x;
}
here may be unused variable may be there.please find and remove it.
I didn't set any preferences to the calculation. just i made up with the flow. if you change the flow the answer will be different. so, Keep in mind. and you can do the same for different operators also.
And One more thing is that, Please verify the equation before proceeding the function. because, it will not check whether the equation is correct or wrong.(a+*d++c). it is not correct equation.
The equation should be correct format.. Like a+b*c-d/x.
Enjoy ..Break the interview and get your correct job..
I'm teaching programming to beginners (starting at 12-15 years old) and one of the choices we made (because it was natural in Python) was to teach the notion of "repeating an action" before the notion of variables.
We warted in Python with
for loop in range(10):
without speaking about variables of arrays and in C++ with
#define repeat(nb) for(int _loop = 0 ; _loop < (nb) ; _loop++)
The idea was to hide the complexity of a classical loop in order to insist on the "repeat" part. We are not hiding from the students the fact that "repeat(10)" is not a part of C++,
it's just a way to simplify the learning.
In Pascal we can't do much more than
for loop := 1 to 10 do
but that's ok because its's not that difficult to remember.
I was looking for something similar in Java and I found that :
import java.util.List;
import java.util.AbstractList;
class Range {
public static List<Integer> size(final int end) {
return new AbstractList<Integer>() {
#Override
public Integer get(int index) {
return 0 + index;
}
#Override
public int size() {
return end;
}
};
};
}
public class Main {
public static void main(String[] argv) {
for (int loop : Range.size(10)) {
System.out.println("xx");
}
}
}
The
for (int loop : Range.size(10))
is still easier to remember than
for(int loop = 0 ; loop < 10 ; loop++)
but there is two problems :
two variables are needed for imbricated for loops : I dont think we can do much about that
we are having warnings because the variable loop is not used
Do you see a better solution that what we have ?
Once again, we only want to provide some "tool" at the beginning phase in order for the students to "repeat" actions, before knowing anything about "variables". We are not hiding from them that's is not in the langage and after a few exercises (~80-100) we are asking them to use the real syntax.
We have approximately 20 exercices before introducing variables : some about printing texts but mostly we are providing one library with objects you can manipulate (hence the variables are hidden in the object state). You can think of the "logo-turtle" for example. This way the notion of "loop" can be manipulated and "seen" before introducing explicit variables and you can have interresting exercises really fast.
One example, in Python, where you want to visit every case of a 10x10 table once and only once and then be back at your starting point (lower-left corner) :
from robot import *
top()
for loop in range(4):
for loop in range(8):
top()
right()
for loop in range(8):
bottom()
right()
for loop in range(8):
top()
right()
for loop in range(9):
bottom()
for loop in range(9):
left()
This exercise is not that easy but the syntax is really simple and allow the student to concentrate on the "algorithmic" part and not the "langage" part.
After a few exercises the students are getting interrested and we can introduce more syntax and more difficult concepts like the variables.
Do you really need to use Java for those exercises? If other languages works for you then why not to use them? You can always move to Java when you students know basics like variables.
I agree that variables can be quite confusing from beginners - especially that their value can change all the time, it is not something people are used from algebra where values don't change once "assigned".
If you want to use Java, you could use while loop which seems to fit better. One dirty trick how to avoid use of variable is following code - it use StackTraceElement instead of variable.
It prints
Hello A
Hello B
Hello C
Hello C
Hello C
Hello B
Hello C
Hello C
Hello C
Hello A
Hello B
Hello C
Hello C
Hello C
Hello B
Hello C
Hello C
Hello C
Hello A
Hello B
Hello C
Hello C
Hello C
Hello B
Hello C
Hello C
Hello C
Here is full source. main(Strinng[] args) method is code with loops, rest is supporting code.
import java.util.HashMap;
import java.util.Map;
public class Repeater {
public static void main(String[] args) {
while(range(3)) {
System.out.println("Hello A");
while (range(2)) {
System.out.println("Hello B");
while (range(3)) {
System.out.println("Hello C");
}
}
}
}
public static boolean range(int size) {
return Range.range(size);
}
public static class Range {
static Map<StackTraceElement, RangePosition> ranges = new HashMap<StackTraceElement, RangePosition>();
public static boolean range(int size) {
final StackTraceElement stackTraceElement = Thread.currentThread().getStackTrace()[3];
//System.out.println(stackTraceElement);
RangePosition position = ranges.get(stackTraceElement);
if (position == null) {
position = new RangePosition();
position.size = size;
ranges.put(stackTraceElement, position);
}
final boolean next = position.next();
if (!next) {
ranges.remove(stackTraceElement);
}
return next;
}
}
public static class RangePosition {
int current,size;
boolean next() {
current++;
return current <= size;
}
}
}
But I'd prefer to use some language which supports this naturally.
I would always introduce variables first. What are you going to do inside the loop without knowledge about variables ?
Apart from that maybe it would be easier to use a while loop. The head of a while loop is much easier and doesn't require variable definitions.
This is very simple to understand:
while (do_the_loop){
//this is repeated
}
Java really is not suitable for this kind of task because it does not allow for functions to be passed.
The only way I can think of doing this without variables would be with an interface:
private static void repeat(int times, DoStuff what) {
for (int i = 0; i < times; i++) {
what.doIt();
}
}
private interface DoStuff {
public void doIt();
}
And then use it this way:
repeat(5, new DoStuff() { public void doIt() {
System.out.println("xx"); // whatever needs to be done
}});
Which would be without variables but quite confusing at the beginning.
This is not really what you are searching for, but here is my opinion and how I would teach it. (Beware, I'm not a teacher at all :D)
Aren't there two different courses for this: Algorithms and Programming? In programming, you really should start off by teaching them the variables. It's not difficult at all. And I don't think that 20 exercises about algorithms are going to be that interesting for them. I think they will be more attracted to the power of computing something than either writing for loops inside each other. Writing a simple program that computes some summations and multiplications et cetera will do to introduce the idea of primitive variables. Then I would introduce the for loop. Demonstrate by printing 10 times some text in combination with the variable used in the for loop:
for (int i = 0; i < 10; ++i)
// Tell them that the 'i' is a variable as you explained before.
{
System.out.println("This is line " + i);
}
Then writing an application that computes the factorial of a hardcoded number will be interesting, I think. This way, most of them will hopefully get the idea of working with variables. Then try to explain scopes.
int number = 5;
int factorial = 1;
for (int i = 1; i <= number; ++i)
{
factorial = factorial * i;
}
System.out.println(number + "! = " + factorial);
if you have a limit defined you have to use a while structure
while(myval < mylimit){
//do something
myval++;
}
but when the limit is unknow then you should use for or for each
for (int i =0; i< list.size();i++)
{
}
of by objects
for each (String myString : myStringArray){
}
Saludos
I am a newbie Computer Science high school student and I have trouble with a small snippet of code. Basically, my code should perform a basic CLI search in an array of integers. However, what happens is I get what appears to be an infinite loop (BlueJ, the compiler I'm using, gets stuck and I have to reset the machine). I have set break points but I still don't quite get the problem...(I don't even understand most of the things that it tells me)
Here's the offending code (assume that "ArrayUtil" works, because it does):
import java.util.Scanner;
public class intSearch
{
public static void main(String[] args)
{
search();
}
public static void search()
{
int[] randomArray = ArrayUtil.randomIntArray(20, 100);
Scanner searchInput = new Scanner(System.in);
int searchInt = searchInput.nextInt();
if (findNumber(randomArray, searchInt) == -1)
{
System.out.println("Error");
}else System.out.println("Searched Number: " + findNumber(randomArray, searchInt));
}
private static int findNumber(int[] searchedArray, int searchTerm)
{
for (int i = 0; searchedArray[i] == searchTerm && i < searchedArray.length; i++)
{
return i;
}
return -1;
}
}
This has been bugging me for some time now...please help me identify the problem!
I don't know about the infinite loop but the following code is not going to work as you intended. The i++ can never be reached so i will always have the value 0.
for (int i = 0; searchedArray[i] == searchTerm && i < searchedArray.length; i++)
{
return i;
}
return -1;
You probably mean this:
for (int i = 0; i < searchedArray.length; i++)
{
if (searchedArray[i] == searchTerm)
{
return i;
}
}
return -1;
I don't know what is the class ArrayUtil (I can not import is using my Netbeans). When I try to change that line with the line int[] randomArray = {1 , 2, 3, 5, 7, 10, 1 , 5}; It works perfectly.
And you should change the loop condition. I will not tell you why but try with my array and you will see the bug soon. After you see it, you can fix it:)
There are 4 basic issues here.
1. Putting searchedArray[i] == searchTerm before i < searchedArray.length can result in an out-of-bounds exception. You must always prevent that kind of code.
2. Your intention seems to be the opposite of your code. Your method name implies finding a search term. But, your code implies that you want to continue your loop scan until the search term is not found, although your loop won't do that either. Think of "for (; this ;) { that } " as "while this do that".
3. Place a break point at the beginning of "search". Then, with a small array, step through the code line by line with the debugger and watch the variables. They don't lie. They will tell you exactly what's happening.
4. Please use a standard IDE and compiler, such as Eclipse and Sun's JDK 6 or 7. Eclipse with JDK 7 is a serious combination that doesn't exhibit a strange "infinite loop" as you describe above.