Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
Write a method changeBlue(weight). Do not change any color of the pixels in the first half of the picture. For the second half, change blue value of each pixel by new blue=original blue * weight.
For example, if a pixel has values (200,100,100) and weight is 0.5,
then the new values will be (200,100,50). If the weight is 1.5, then
the new values will be (200,100,150).
You can use any image to test this method.
Here's what I have. I think I'm pretty close, but I'm getting some errors. Any advice is appreciated.
public void changeBlue(int weight)
{
Pixel[] pixelArray = this.getPixels();
Pixel pixelObj = null;
int value = 0;
int index = 0;
while (index >= pixelArray.length/2)
{
pixelObj = pixelArray[index];
value = pixelObj.getBlue();
value = (value * weight);
pixelObj.setBlue(value);
index++;
}
}
For a start, the parameter of the changeBluemethod is an int, shouldn't this be a double given your specification?
You also have index initially set to 0, and your loop only runs whilst index >= half the pixel array length (pixels.length / 2). So this loop won't ever start unless pixels.length / 2 returns 0. Once it has started, it'll also never terminate.
You would be best to use a for statement. Initialise an int to half the array length (pixels.length / 2), set it to terminate after the loop executes the last pixels array index (pixels.length - 1), and make sure it increments by 1 each time.
See https://docs.oracle.com/javase/tutorial/java/nutsandbolts/for.html for details and how to use a for statement.
Additionally, if setBlue() takes an int as a parameter, you should cast it. e.g. (int) (weight * value). But you do not provide any details of the Pixel class.
Example implementation:
public void changeBlue(double weight) {
for (int i = pixelArray.length / 2; i < pixelArray.length; i++) {
pixelArray[i].setBlue((int) (pixelArray[i].getBlue() * weight));
}
}
On a practical note, if blue becomes 0 you won't be able to change it using changeBlue, but this behaviour would be somewhat logical in this case.
Not the best implementation but try :
public void changeBlue(int weight)
{
Pixel[] pixelArray = this.getPixels();
Pixel pixelObj = null;
int value = 0;
int index = 0;
int halfSize = pixelArray.length/2;
for (index = 0; index <= pixelArray.length; index++) {
if (index <= halfSize){
// FIrts half of the file
}
if (index > halfSize) {
// Seconde part of the file
pixelObj = pixelArray[index];
value = pixelObj.getBlue();
value = (value * weight);
pixelObj.setBlue(value);
}
}
}
Related
This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 4 years ago.
I currently have a problem with creating objects using two-dimensional arrays in Java.
I'ld like to display bricks on a playing board (like in the classic "BreakOut games), therefore I created a class "Stone" for the stone-objects, the constructor of the class is:
public Stone (Position pos, int value){
this.pos = pos;
this.type = type;
}
I also created a 2D-array (int) called "stoneTypes" for the pattern of the Stones, in which I saved a matrix from a JSON file.
I ld' now like to create Stone-objects in my class "Level" by using the values of the stoneTypes-matrix, which currently looks like this (I included an if-condition, so Stone-objects are only created for stoneTypes value >= 1):
private Stone[][] stones = new Stone[25][20];
private int[][] stoneTypes;
JSONReader reader = new JSONReader("res/Level" + levelnr +".json");
stoneTypes = reader.getStones2DArray();
for (int w = 0; w < stoneTypes.length; w++) {
for (int h = 0; h < stoneTypes[w].length; h++) {
if (stoneTypes [w][h] >= 1) {
Position pos = new Position(width * w, height * h);
this.stones[w][h] = new Stone(pos, stoneTypes[w][h]);
}
}
}
I also included a get-Method for the Stone-array, so I could use it to draw the Stones in my "Field" class:
public Stone[][] getStones(){
return this.stones;
}
The method for drawing the Stones in my "Field" class currently looks like this:
private void drawStones(Graphics2D g2) {
stones = view.getGame().getLevel().getStones();
for (int i = 0; i < stones.length; i++) {
for (int j = 0; j < stones[i].length; j++) {
*** int x_position = (int) stones[i][j].getPosition().getX(); ***
int y_position = (int) stones[i][j].getPosition().getY();
g2.fillRoundRect(x_position, y_position,
(int) ((double)Constants.SCREEN_WIDTH/Constants.SQUARES_X)-2,
(int) ((double)Constants.SCREEN_HEIGHT/Constants.SQUARES_Y)-2 ,1,1);
System.out.println(x_position);
}
}
}
Eclipse doesn't show any syntax errors but I do receive a NullPointerException at the spot I marked with the ***, as soon as I start the programm. I am not sure if my get-Method isn't implemented correctly or if the process of creating new Stone-objects is simply wrong. I tried hundreds of things but couldn't find a solution, I hope you guys can help me.
Thx in advance, Scoopa!
Here:
if (stoneTypes [w][h] >= 1) {
Position pos = new Position(width * w, height * h);
this.stones[w][h] = new Stone(pos, stoneTypes[w][h]);
}
You are only creating new stones when that condition is met. All other fields will stay with their default initial value. And that would be: null.
When you do that, you can't just go in (unconditionally) and do:
int x_position = (int) stones[i][j].getPosition().getX()
You would need a
if (stones[i][j] != null)
to guard such accesses!
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
How do I remove the first digit of an integer?
My input is an integer (for example i = 123456789).
I then want to remove the first digit, so that i equals 23456789.
try this
n = n % (int) Math.pow(10, (int) Math.log10(n));
Here is one way to do it:
Convert it to String
Take the substring without the first "digit"
Convert it to int
Code:
public static void main(String[] args)
{
int x = 123456789;
String x_str = Integer.toString(x);
int new_x = Integer.parseInt(x_str.substring(1));
System.out.println(new_x);
}
Output:
23456789
Note: This can be done in one line with
int x = 123456789;
int new_x = Integer.parseInt(Integer.toString(x).substring(1));
Edit:
To handle negative-case, check if number is positive or integer:
int new_x = Integer.parseInt(x > 0 ?
Integer.toString(x).substring(1) : Integer.toString(x).substring(2));
If you want to avoid the string conversion, you can find the high digit and subtract it.
public static void main(String[] args) {
int x = 123456789;
System.out.println("x = " + x);
int hi = x, n = 0;
while (hi > 9) {
hi /= 10;
++n;
}
for (int i = 0; i < n; i++) hi *= 10;
x -= hi;
System.out.println("x with high digit removed = " + x);
}
Here's the one-line, purely numeric solution:
i %= (int) Math.pow(10, (int) Math.log10(i));
Alternate approach:
int stripLeading(int i) {
if(i > 0) {
return i - (int)Math.pow(10, (int)Math.log10(i));
} else if(i > 0) {
return i + (int)Math.pow(10, (int)Math.log(-i+1));
} else {
return 0;
}
}
I think I remember the string-free version of this … although I totally agree with #Christian as how I would do it…
NOTE: as #Darren Gilroy pointed out, one must consider negatives and zero spocially, and my function fails to do so.
Of course % is a better solution also.
public static void main (String [] argv)
{
final int x = 123456789;
int newX = x;
/* How many digits are there? */
final double originalLog = Math.floor (Math.log10 (x));
/* Let's subtract 10 to that power until the number is smaller */
final int getRidOf = (int)Math.pow (10, originalLog);
while (originalLog == Math.floor (Math.log10 (newX)))
{ newX -= getRidOf; }
System.out.println (newX);
}
Poor profiling attempt:
Looping the above function without the println for 20,000,000,000 repeats in a for loop:
real 0m9.943s
user 0m9.890s
sys 0m0.028s
The same with Christian's far-easier-to-understand and perfectly functionable version, but for only 200,000,000 repeats (because I'm lazy and got tired of waiting):
real 0m18.581s
user 0m17.972s
sys 0m0.574s
So one might argue that constructing the String objects is probably slowing it down by roughly 200×, but that isn't a really finely-tuned profiling set-up.
If you want to go for simpler methods and without using String, then here's my simple take:
Count number of digits int the integer.
Divide the int by 10^n. n is the number of digits.
Obtain absolute value of the result. //In case of (-)ve numbers.
For example
int i = 123456789;
int n = getDigitCount(i);
int r = Math.abs(i / (int)Math.pow(10,n)); //r stores result.
And you'd require this method:
int getDigitCount(int num)
{
int c = 0;
while(num > 0){
num/=10;
c++;
}
return c;
}
trying to initialize my array at 1 and have it double every time it's input fills up. this is what i have right now
int max = 1;
PhoneRecord[] records = new PhoneRecord[max];
int numRecords = 0;
int size = Integer.parseInt(length.records[numRecords]);
if (size >= max) {
size = 2*size;
}
but it's clearly full of fail. any suggestions or guidance would be great, thanks.
OK, you should use an ArrayList, but several other folks already told you that.
If you still want to use an array, here's how you'd resize it:
int max = 1;
PhoneRecord[] records = new PhoneRecord[max];
int numRecords = 0;
void addRecord(PhoneRecord rec) {
records[numRecords++] = rec;
if(numRecords == max) {
/* out of space, double the array size */
max *= 2;
records = Arrays.copyOf(records, max);
}
}
Why not use an ArrayList ? It'll exhibit very similar characteristics automatically.
From the private grow() method:
int newCapacity = oldCapacity + (oldCapacity >> 1);
You can't override the growth behaviour, but unless you really require a doubling due to your app characteristics, I'm sure it'll be sufficient.
Size is only multiplying the size number, not double the array size.
Try:
records = Arrays.copyOf(records, records.length*2);
For this question: Is there a proper algorithm for detecting the background color of a figure?, I will need to create a flood-fill algorithm to be able to separate all my pixels in groups of the same color.
I did this recursively, but it gives me a stack-overflow error. So I had to choose the iterative, queue based algorithm found here: http://en.wikipedia.org/wiki/Flood_fill#Alternative_implementations
First of all, I begin a search over all the matrix elements (elements being instances of the Pixel class).
private PixelGroup[] generatePixelGroupsFromMatrix(Pixel[][] matrix) {
PixelGroup[] tempGroups = new PixelGroups[9999999]; // Nevermind the 9999999....
int groupsFound = 0;
Pixel pixel;
for (int y = 0; y < matrix.length; ++y) {
for (int x = 0; x < matrix[0].length; ++x) {
pixel = matrix[y][x];
if (!pixel.evaluated) {
// This pixel has never been evaluated
// Therefore, it belongs to a new group
// First, we make a new group
PixelGroup newGroup = new PixelGroup();
// Begin search for connected pixels with the same color. All pixels found will belong to this new group.
findPixelsConnectedWith(pixel,newGroup);
tempGroups[groupsFound] = newGroup;
++groupsFound;
}
}
}
PixelGroup[] result = new PixelGroup[groupsFound];
for (int i = 0; i < groupsFound; ++i) {
result[i] = tempGroups[i];
}
return result;
}
So, Pixel has the following values: x, y, evaluated (boolean) and color (integer).
Then, PixelGroup is simply a class capable of holding pixels (it works).
And this is the method that is giving me trouble:
private void findPixelsConnectedWith(Pixel pixel, GroupOfPixels group) {
QueueOfPixels queue = new QueueOfPixels();
queue.add(pixel);
Pixel currentPixel;
int x,y;
Pixel neighbor;
while((currentPixel = queue.nextPixel()) != null) {
if (currentPixel.color == pixel.color && !currentPixel.evaluated) {
// This pixel has the required color, and has not been evaluated. It meets our needs.
// Add to group.
group.addPixel(currentPixel);
// Flag it as evaluated. So in the future, it will be ignored.
currentPixel.evaluated = true;
// Evaluate all 8 possible directions to find neighbor pixels
int[] xDirections = {0,1,1,1,0,-1,-1,-1};
int[] yDirections = {-1,-1,0,1,1,1,0,-1};
for (int i = 0; i < 8; ++i) {
x = xDirections[i];
y = yDirections[i];
if (pixelExists(currentPixel.y + y,currentPixel.x + x)) {
// There exists a pixel in this direction!
neighbor = getPixel(currentPixel.y + y,currentPixel.x + x);
queue.add(neighbor);
}
}
}
}
}
If you're curious, here is my QueueOfPixels class. I had to make my own with only vectors (school assignment requirement): https://codereview.stackexchange.com/questions/17823/vector-based-flood-fill-algorithm-queue-class (as far as I can tell, it simply works).
WHAT IS THE PROBLEM?
Alright, I have tested this with this image, which is 5x2 pixels (you'll need to zoom in a lot to see it): http://i.stack.imgur.com/xV0Lf.gif - the first row only has black pixels, and the second they're white. The program tells me it has found 6 pixel groups (when it should have been only 2!)
WHAT HAVE I TRIED TO DEBUG THE PROBLEM?
Well, first, before calling findPixelsConnectedWith, I placed this line:
System.out.println("The pixel (" + x + "," + y + ") has not been evaluated. Evaluating now.");
And this was the result:
The pixel (0,0) has not been evaluated. Evaluating now.
The pixel (1,0) has not been evaluated. Evaluating now.
The pixel (2,0) has not been evaluated. Evaluating now.
The pixel (3,0) has not been evaluated. Evaluating now.
The pixel (4,0) has not been evaluated. Evaluating now.
The pixel (0,1) has not been evaluated. Evaluating now.
So, as you can see, it seems like the code is unable to work with the first row (black pixels) since it thinks that every pixel in that row has not been evaluated (I expected it to say that (0,0) was not evaluated and done). But when it starts working with the second row, it does seem to work as expected (find (0,1) and then it is over).
But I still am unable to find out what is going on. Any ideas?
Edit:
My getPixel and pixelExists functions:
private boolean pixelExists(int y, int x) {
return (y > 0 && y < pixelMatrix.length) && (x > 0 && x < pixelMatrix[0].length);
}
private Pixel getPixel(int y, int x) {
return pixelMatrix[y][x];
}
Your pixelExists method should use y >= 0 and x >= 0 instead of y > 0 and x > 0.
private boolean pixelExists(int y, int x) {
return (y >= 0 && y < pixelMatrix.length) && (x >= 0 && x < pixelMatrix[0].length);
}
This may not be the only problem, but it will certainly prevent you from getting the correct answers.
Maybe pixelExists method has "y > 0" part while it should has "y>=0"?
I have problem with comparing the value of array elements.
e.g. I wanted to compare the value of index 0 and index 2, and index 1 to index 3 and so on.
With the code below I suppose to get the result of numOfdifferentShape is 2 but I get 3.
How can I solve this problem? :-(
int numOfdifferentShape=0;
myArray = {40.0, 40.0, 40.0, 40.0, 80.0, 40.0, 40.0, 40.0}
for (int a=0; int a<myArray.size(); a=a+2)
{
for (int b=a+2; b<myArray.size; b=b+2)
{
if (!(myArray.get(a).equals(myArray.get(b) && myArray.get(a+1).equals(b+1)))
numOfdifferentShape++;
break;
}
}
There are several syntax errors in this code, but since TofuBeer has already pointed them out in the comments, I'll move on the the design and logic.
Going from the code, I'm assuming you don't have much experience with Java, and perhaps not with programming at all. So I'm going to go slowly here. I hope you aren't insulted by my explanations.
You say you are trying to find out how many of the objects which you are storing (as two ints) in your array are equal. To do this, you have to keep track of what unique objects you have already seen. Then you compare each object the list of unique objects and, if it doesn't match any of them, add it to the list. This is the basic algorithm.
Now, have you noticed that I keep using the word "object" in my description? When that happens, it usually means you should be making a class. I would make a simple one like this, holding the two integers:
class Box { // or whatever the objects are called
private final int height;
private final int width;
public Box(int h, int w) {
height = h;
width = w;
}
public int getHeight() {
return height;
}
public int getWidth() {
return width;
}
#Override
public boolean equals(Object other) {
if (!(other instanceof Box))
return false;
Box b = (Box) other;
return b.height == height && b.width == width;
}
#Override
public int hashCode() {
int hash = 7;
hash = 97 * hash + this.height;
hash = 97 * hash + this.width;
return hash;
}
}
Try to understand what each part of this code does (especially if this is actually your homework). Once you've got it, move on to the next part: doing the calculation that you were trying to do.
Let's say you have an array of Boxes, like this:
Box[] boxes = {
new Box(40, 40), new Box(40, 40), new Box(80, 40), new Box(40, 40)
};
(I can't tell if you're using an array or a list, so I'm just picking one to demonstrate.)
I already gave the algorithm for finding the number of unique items, so I'll show you how I would write it:
List<Box> unique = new ArrayList<Box>();
for (Box box : boxes) {
if (!unique.contains(box)) { // this is why I implemented equals() and hashCode()!
unique.add(box);
}
}
int numOfDifferentShape = unique.size();
This is much easier than trying to keep track of two ints for each object, plus it has the advantage that you can't get your array indices confused.
You could do this even more easily with a Set. It would look something like this:
Set<Box> boxSet = new HashSet<Box>();
for (Box b : boxes)
boxSet.add(b);
int numOfDifferentShape = boxSet.size();
Note that these last two snippets use features from Java 1.5, so I don't know if you've run into them before.
Does this make things clearer?
for (int i = 0; i < (myArray.size() - 2); ++i)
{
if (myArray[i] != myArray[i + 2])
++numOfdifferentShapes;
}
You have two loops, your description suggests you only want one.
You need to do bounds checking - do you want the n+2 to wrap to the start to the start of the array when it exceeds the length?
I think you have a parentheses problem. You wrote:
if (!(myArray.get(a).equals(myArray.get(b) && myArray.get(a+1).equals(b+1)))
when I think you mean:
if (!(myArray.get(a).equals(myArray.get(b)) && myArray.get(a+1).equals(b+1))
Also, in the same line, instead of:
equals(b+1)
don't you mean
myArray.get(b+1)
I have array list e.g.
{40,40,80,20,40,40} I wanted to
compare the elements. Even number of
index (e.g. index 0, index 2, index 4
etc) represents Height of an object
and Odd number of Index (e.g. index 1,
index 3 ec) represent Width of an
object. So, with the code above,
Object 1 (index 0 and 1).
Why not make an array of a Dimension class, something like this:
public class Dimension
{
private final int width;
private final int height;
public Dimension(final int w,
final int h)
{
width = w;
height = h;
}
public int getWidth()
{
return (width);
}
public int getHeight()
{
return (height);
}
}
then do a for loop something like this:
for(int i = 0; i < array.length; i += 2)
{
final Dimension a;
final Dimension b;
a = array[i];
b = array[i + 1];
// compare a.getLength() to b.getLength()
// or
// compare a.getWidth() to b.getWidth()
}
It is usually a bad idea to try and be "tricky" - saying even ones are with and odd ones are length is being tricky... bad idea IMO.