issues in indexing a class in Java - java

I have happened to have a problem in defining an array where the index should be elements of a class as follows:
MWE:
package thisModel;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class ThisCode {
public static void main(String[] args) {
class Arc {
private int i; //starting node
private int j; // ending node
public Arc(int i, int j) {
this.i = i;
this.j = j;
}
#Override
public String toString() {
return Integer.toString(i) + " " + Integer.toString(j);
}
}
List<Arc> arcs = new ArrayList<Arc>();
int N = 7;
int [] b = new int [N];
}
}
so, here, if I define the array as follows:
int [] y = new int [arcs.size()];
Then, errors are popping up in the following loop:
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
//my issue lies here:
//y[Arc(i,j)] - y[Arc(j,i)] = b[i];
}
}
and I think it is because y[arcs.size()] has a dimension of the size of the list, but not its elements.
My question is if there is any way to define the y like as an array of Arc not arcs.size() like this:
int[] y = new int [Arc(i,j)];

If you type y as a two-dimensional array
int[][] y = new int[N][N];
then you can use the Arc's components i and j as index of y to retrieve values:
int value = y[i][j];
You can also type it as a Map (if I read your first sentence literally):
Map<Arc, Integer> y = new HashMap<>();
This allows you to get values from y by asking for them with a particular Arc instance:
Arc myArc = ...;
int value = y.get(myArc);
In this case you should define proper hashCode and equals methods in your Arc class:
#Override
public boolean equals(Object x) {
if (!(x instanceof Arc)) return false;
Arc that = (Arc) x;
return this.i == that.i && this.j == that.j;
}
#Override
public int hashCode() {
return this.i + 31*this.j;
}
otherwise the HashMap will not find any values if you try to get them by passing new Arc instances with same components to it.

Related

Is there a way to declare a 2 dimensional array of List in a type safe manner in Java? [duplicate]

This question already has answers here:
Type Cannot create a generic array of List<FooClass>
(3 answers)
"Cannot create generic array of .." - how to create an Array of Map<String, Object>?
(6 answers)
Closed 1 year ago.
Here is the code I have that works but with a type safety warning when I size and instantiate the array:
import java.util.ArrayList;
import java.util.List;
public class Test {
private static final int MAX_ROWS = 2;
private static final int MAX_COLS = 5;
private List<String> _stringSets[][];
public Test() {
_stringSets = new List[MAX_ROWS][MAX_COLS];
for(int row = 0; row < MAX_ROWS; row++) {
for(int col = 0; col < MAX_COLS; col++) {
_stringSets[row][col] = new ArrayList<String>();
}
}
}
}
I tried
_stringSets = new List<String>[MAX_ROWS][MAX_COLS];
but this won't work...
Lists are unidimensional and would be declared something like this:
List<String> myList = new ArrayList<>()
When you seem to be looking for a 2-dimensional arrays, which are declared something like this:
String[][] myArray = new String[n1][n2]
So what you want is probably something along those lines:
public class Test {
private static final int MAX_ROWS = 2;
private static final int MAX_COLS = 5;
private String[][] stringSets;
public Test() {
stringSets = new String[MAX_ROWS][MAX_COLS];
for(int row = 0; row < MAX_ROWS; row++) {
for(int col = 0; col < MAX_COLS; col++) {
stringSets[row][col] = row+"-"+col;
}
}
}
}
Generally not recommended to mix Arrays and Lists in this way. May want to consider using other data structures to achieve a similar effect instead. For example, you could create a Map that uses Position coordinates to achieve similar results.
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
public class MapList {
private static Map<Position, List<Integer>> mapList;
public static void main(String[] args) {
final int MAX_X = 5;
final int MAX_Y = 6;
mapList = new HashMap<>();
for(int i = 0; i < MAX_X; i++) {
for(int j = 0; j < MAX_Y; j++) {
mapList.put(new Position(i, j), new ArrayList<>());
for(int k = 0; k < 5; k++) {
mapList.get(new Position(i, j)).add(k);
}
}
}
for(Position p : mapList.keySet())
System.out.println(p.toString() + mapList.get(p));
}
private static class Position {
private Integer x;
private Integer y;
public Position(Integer x, Integer y) {
this.x = x;
this.y = y;
}
#Override
public boolean equals(Object o) {
if(this == o)
return true;
if(o == null)
return false;
if(getClass() != o.getClass())
return false;
Position other = (Position) o;
return x == other.x && y == other.y;
}
#Override
public int hashCode() {
return Objects.hash(x, y);
}
#Override
public String toString() {
return "(x:" + x + ", y:" + y + ")";
}
}
}

BFS using Adjecency Matrix

Question to find Bfs path ,, i am able to code bfs path if the graph have vertices marked as 0,1,2,3,4,,like this
But can't able to apply adjacency matrix how to solve bfs for graph like 5,10,15,20
attached images what i have coded
solution
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
public class Bfs {
public static void bfsTraversal(int[][] adjMatrix) {
Queue<Integer> pendingVertices = new LinkedList<>();
boolean[] visited = new boolean[adjMatrix.length];
visited[0] = true;
pendingVertices.add(0);
while (!pendingVertices.isEmpty()) {
int currentVertex = pendingVertices.poll();
System.out.print(currentVertex + " ");
for (int i = 0; i < adjMatrix.length; i++) {
if (adjMatrix[currentVertex][i] == 1 && !visited[i]) {
pendingVertices.add(i);
visited[i] = true;
}
}
}
}
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
int v = s.nextInt();
int e = s.nextInt();
int[][] adjMatrix = new int[v][v];
for (int i = 0; i < e; i++) {
int v1 = s.nextInt();
int v2 = s.nextInt();
adjMatrix[v1][v2] = 1;
adjMatrix[v2][v1] = 1;
}
bfsTraversal(adjMatrix);
}
}
Click here for Question for bfs like vertices 0,1,2,3,4...
Click here for ,How i want to solve this for bfs like vertices 5,10,15,20...
And i want to do the same for graph like this ,,can't get logic
Solved by mapping the input with 0,1,2,3.... and maintained a reverseMap
Click here to view the Solution
If you know the range of the numbers, you can let the numbers 5, 10, 15 and 20 be the IDs of the nodes and store the indices of the nodes in a seperate array. Suppose the name of the array is IndexLookupArray, if you want to lookup the index of a node with ID x you can find it in IndexLookupArray[x]. And the rest of the code should be the same. If the range of the numbers is unknown or if it's too big to fit in an array, you can store the indices in a hash map for example and do the same thing.
You can write something like this:
import java.util.Arrays;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
public class Bfs {
public static void bfsTraversal(int[][] adjMatrix) {
Queue<Integer> pendingVertices = new LinkedList<>();
boolean[] visited = new boolean[adjMatrix.length];
visited[0] = true;
pendingVertices.add(0);
while (!pendingVertices.isEmpty()) {
int currentVertex = pendingVertices.poll();
System.out.print(currentVertex + " ");
for (int i = 0; i < adjMatrix.length; i++) {
if (adjMatrix[currentVertex][i] == 1 && !visited[i]) {
pendingVertices.add(i);
visited[i] = true;
}
}
}
}
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
int idx = 0;
int range = s.nextInt();
int v = s.nextInt();
int e = s.nextInt();
int[] IndexLookupArray = new int[range + 1]; // range + 1 since IndexLookupArray[range] should be accessible.
int[][] adjMatrix = new int[v][v];
Arrays.fill(IndexLookupArray, 0, range + 1, -1);
for (int i = 0; i < e; i++) {
int v1 = s.nextInt();
if (IndexLookupArray[v1] == -1)
{
IndexLookupArray[v1] = idx;
idx++;
}
v1 = IndexLookupArray[v1];
int v2 = s.nextInt();
if (IndexLookupArray[v2] == -1)
{
IndexLookupArray[v2] = idx;
idx++;
}
v2 = IndexLookupArray[v2];
adjMatrix[v1][v2] = 1;
adjMatrix[v2][v1] = 1;
}
bfsTraversal(adjMatrix);
}
}

Trouble calling method and Populating Random Array

I am new to coding and trying to call a method (RandomArray) which I wrote and defined in a separate class, but in my driver code I am getting following error message:
Couldn't find symbol- RandomArray().
the code SHOULD create an array (size of which is chosen by the user) and then populate it with random numbers and output the Highest, Lowest, and Average of the numbers in said array.
All spellings match up, and the call itself works and displays no errors, but when using it in the for-loop I get the error message.
This is the class where I created the method:
import java.util.Random;
public class RandomArray
{
//things declared at class level
public int minimun,maximun,adverage, mn, mx, avg;
public String range;
//constucotr for inital numbers
public RandomArray()
{
minimun = 0;
maximun = 1000 + 1;
}
static int RandomArray()
{
Random ran = new Random();
return (ran.nextInt(1000) + 1);
}
//define types
public RandomArray (int mn, int mx, String r, int a)
{
minimun = mn;
maximun = mx;
range = r;
adverage = a;
}
//set minimun
public void setMinimun (int m)
{
minimun = mn;
}
//get minimun
public int getMinimun()
{
return minimun;
}
//set maximun
public void setMaximun(int x)
{
maximun = mx;
}
//get maximun
public int getMaximun()
{
return maximun;
}
//compute adverage
public int adverage(int...array)
{
int adverage = 0;
if (array.length > 0)
{
int sum = 0;
for(int num : array)
sum = sum + num; //add numbers in array
adverage = (int)sum / array.length; //divide numbers in array by the array lenth
}
return adverage;
}
//return values as a string
public String toString()
{
return String.valueOf(getMinimun() + getMaximun() + adverage());
}
}
And this is the driver program that should be populating the array (of users choice) with random numbers and printing the highest, lowest and average:
import java.util.Random;
import java.util.Scanner;
import java.util.Arrays;
public class DemoRandomArray
{
// variable go here
final int minimun = 0;
public static void main(String[] args)
{
final int max = 100;
RandomArray ra = new RandomArray();
int[] anArray = new int[1000];
for(int i=1; i < max; i++)
{
System.out.println(RandomArray());
}
}
}
The method is inside another class, so you need to use the class name.
RandomArray.RandomArray() instead of just RandomArray()

What am I doing wrong with my image denoising method?

I've been trying to denoise my image by using a median filter as described in this article
I'm only doing one pass until I get this thing working. The result is largely a washed out image, as seen below.
A minimal working version of my code is below:
import java.awt.image.BufferedImage;
import java.util.Arrays;
public class Denoise {
public static void main(String args[]) {
String directory = "C:\\Users\\Speedy Octopus\\Desktop\\Place Car Folders Here\\Original\\15.JPG";
BufferedImage image = ImageUtility.loadImage(directory);
for (int iterationCount = 0; iterationCount < 1; iterationCount++){
for (int i = 1; i < image.getWidth()-1; i++) {
for (int j = 1; j < image.getHeight()-1; j++) {
image.setRGB(i, j, getMedianPixelValue(image, i, j));
}
}
}
String directory2 = "C:\\Users\\Speedy Octopus\\Desktop\\Place Car Folders Here\\Original\\152.JPG";
Controller.saveImage(image, directory2);
}
public static int getMedianPixelValue(BufferedImage image, int i, int j) {
int[] surroundingPixels = new int[8];
int iter = 0;
for (int q = i-1; q<=i+1; q++) {
for (int r = j-1; r<=j+1;r++) {
if (!(q == i && r == j)) {
surroundingPixels[iter] = image.getRGB(q, r);
iter++;
}
}
}
Arrays.sort(surroundingPixels);
int medianIndex = surroundingPixels.length/2;
int medianPixel = surroundingPixels[medianIndex];
return medianPixel;
}
}
As I answered in this question Applying Mean filter on an image using java getRGB "Returns an integer pixel in the default RGB color model (TYPE_INT_ARGB)" so you have to extract and remove the alpha (A) component before you do any comparisons:
pixel=image.getRGB(i, j)&0x00ffffff;
in the media sorting etc
And you can extract the R, G, and B and process them separately, or do the comparison on the whole pixel RGB - you can experiment either way.

Accessing ArrayList<ArrayList<SomeObject>> elements

I have an ArrayList of ArrayLists where i need to find a simple way of accessing the elements, to make it easier to understand i have drawn my goal of what i want to achieve:
As seen on the image above the main ArrayList consists of m ArrayList, where i wish to get an element by using a get method which goes from 0 to N elements, where N is the total elements of ArrayList1 and ArrayList2. More ArrayList's may occur.
I can of course iterate through the elements by using two for-loops, which is not what im searching for in this case.
You would need to basically have the the ArrayList members on your new wrapper class and implement them in a different manner. I whipped up an example that demonstrates the correct index being calculated in get().
import java.util.ArrayList;
public class ListHolder<T> {
public ArrayList<ArrayList<T>> list = new ArrayList<ArrayList<T>>();
public int size() {
int size = 0;
for (int i = 0; i < list.size(); i++) {
size += list.get(i).size();
}
return size;
}
public T get(int i) {
if (i >= size())
return null;
int listIndex = 0;
int valueIndex = i;
while (valueIndex >= list.get(listIndex).size()) {
valueIndex -= list.get(listIndex++).size();
}
return list.get(listIndex).get(valueIndex);
}
}
What I used to verify my methods:
public static void main(String[] args)
{
ListHolder<Object> listHolder = new ListHolder<Object>();
listHolder.list.add(new ArrayList<Object>());
listHolder.list.get(0).add("hello");
listHolder.list.get(0).add("world");
listHolder.list.add(new ArrayList<Object>());
listHolder.list.get(1).add("a");
listHolder.list.get(1).add("b");
listHolder.list.get(1).add("c");
System.out.println("Size: " + listHolder.size());
System.out.println("listHolder[0]: " + listHolder.get(0)); // "hello"
System.out.println("listHolder[1]: " + listHolder.get(1)); // "world"
System.out.println("listHolder[2]: " + listHolder.get(2)); // "a"
System.out.println("listHolder[3]: " + listHolder.get(3)); // "b"
System.out.println("listHolder[4]: " + listHolder.get(4)); // "c"
System.out.println("listHolder[5]: " + listHolder.get(5)); // "null"
}
You don't provide many details about what these lists are, and if they're mutable or not. But you could probably use an additional list containing all the elements of all the sublists:
private class Generation
private List<List<Element>> populations = new ArrayList<>();
private List<Element> allElements = new ArrayList<>();
public Element getElementAt(int elementIndex) {
return allElements.get(elementIndex);
}
public void addPopulation(List<Element> population) {
populations.add(new ArrayList<>(population));
allElements.addAll(population);
}
public List<Element> getPopulationAt(int populationIndex) {
return Collections.unmodifiableList(populations.get(populationIndex));
}
}
class Plot {
class Point {
int x;
int y;
}
List<List<Point>> area = new ArrayList<List<Point>>();
Point getPoint (int x, int y) throws IndexOutOfBoundsException {
if (x < 0 && x >= area.size())
throw new IndexOutOfBoundsException();
int l = area.get(x).size();
int i = (int)y/l;
int j = y % l;
return area.get(x+i).get(j);
}
void setPoint (int x, int y, Point p) throws IndexOutOfBoundsException {
if (x < 0 && x >= area.size())
throw new IndexOutOfBoundsException();
int l = area.get(x).size();
int i = (int)y/l;
int j = y % l;
area.get(x+i).set(j, p);
}
}

Categories