remove an object from an array without using arraylist - java

I know this question has been asked but I couldn't use the solutions of it to do what I want to do
My problem is every time I call from the function and enter an Id it always tells me that the id was removed even if I entered an id that was never entered it still prints the same
any tip and help would be appreciated :)
Note: I don't want to use ArrayList in it
here is my code :
public Members[] deleteMembers(String id) {
if (id == null)
return member;
Members[] copyId = new Members[member.length - 1];
for (int i = 0, k = 0; i < member.length; i++) {
if (member[i].getId().equals(id)) {
continue;
}
copyId[k++] = member[i];
}
return copyId;
}

You have only one problem. Do not forget, that array could not have an item with a given id.
public static Member[] deleteMember(String id, Member[] members) {
if (id == null || members == null)
return members;
int pos = findMemberPos(id, members);
if (pos == -1)
return members;
Member[] arr = new Member[members.length - 1];
for (int i = 0, j = 0; i < members.length; i++)
if (i != pos)
arr[i] = members[j++];
return arr;
}
private static int findMemberPos(String id, Member[] members) {
for (int i = 0; i < members.length; i++)
if (id.equalsIgnoreCase(members[i].getId()))
return i;
return -1;
}

That should work
public Members[] deleteMembers(String id) {
if (id == null)
return member;
if (!doArrayContainsId(id)) {
return member;
}
Members[] copyId = new Members[member.length - 1];
for (int i = 0, k = 0; i < member.length; i++) {
if (member[i].getId().equals(id)) {
continue;
}
copyId[k++] = member[i];
}
return copyId;
}
public boolean doArrayContainsId(String id) {
if (id == null) {
return false;
}
boolean doArrayContainsId = false;
for (Members members : member) {
if (members.getId().equals(id)) {
doArrayContainsId = true;
break;
}
}
return doArrayContainsId;
}
Btw you should try to name your classes a bit better like Member instead of Members since one object is one member and array or list of them should be called members

Related

How to make this method only have 1 return statement instead of 2

My professor has a rule that "there should be no more than one return statement in any method". Now I've written a pretty simple method in my first project. How would I make this have only return statement without ruining functionality?
public static int find(int correctNumber, int numArray[], int lastNum) {
for (int i = 0; i < lastNum; i++) {
if (numArray[i] == correctNumber) {
return i;
}
}
return -1;
Use another variable to assign the value and then apply a break within the if clause to exit the loop.
public static int find(int correctNumber, int numArray[], int lastNum) {
int returnValue = -1;
for (int i = 0; i < lastNum; i++) {
if (numArray[i] == correctNumber) {
returnValue = i;
break;
}
}
return returnValue;
}
And you will find that many professional programmers with lots of experience find it perfectly acceptable to use multiple return statements.
For example: This is the equals override from the JDK HashMap source. That code was written by four internationally recognized computer scientists, three of which have their PhD's.
public final boolean equals(Object o) {
if (o == this)
return true;
if (o instanceof Map.Entry) {
Map.Entry<?,?> e = (Map.Entry<?,?>)o;
if (Objects.equals(key, e.getKey()) &&
Objects.equals(value, e.getValue()))
return true;
}
return false;
}
like this?
public static int find(int correctNumber, int numArray[], int lastNum) {
int correctIndex = -1;
for (int i = 0; i < lastNum; i++) {
if (numArray[i] == correctNumber) {
correctIndex = i;
}
}
return correctIndex;
you can try this:
public static int find(int correctNumber, int numArray[], int lastNum) {
int temNum = -1;
for (int i = 0; i < lastNum; i++) {
if (numArray[i] == correctNumber) {
temNum = i;
break;
}
}
return temNum;
}
public static int find(int correctNumber, int numArray[], int lastNum) {
int i = lastNum - 1;
while (i >= 0 && numArray[i] != correctNumber) {
i--;
}
return i;
}
This differs slightly from your code in that, if the 'correctNumber' occurs twice, it will find the higher-index instance.
It could be expressed with a for-loop but I find I prefer the while-loop.
public static int find(int correctNumber, int numArray[], int lastNum) {
int i;
for (i = lastNum-1; i >= 0 && numArray[i] != correctNumber; i--) {
}
return i;
}

Java assignment to use Dijkstras search method, breath-first and depth first

Hello StackOverflow community, need your help. I have a final for my java class and its asking for:
Generate a graph with 100,000 nodes, where each node randomly has between 1 and 5 connections to other nodes. Each node should contain within it a random value between 1 and 300,000. (So generally about 1 in 3 searches will yield a query match). Allow the user to enter a number to search for, and implement each of the following three types of searching algorithms. Breadth-First. (30 points) Depth-First. (30 points) Dijkstra's Algorithm. (40 points)
Do not allow back-tracking in your searches. (Mark nodes that you already searched as complete, and do not re-visit them in the same search). Each search should return the following: The Success/Failure of your search. The length of the shortest path to the found node. The total number of nodes examined during the search. Optionally you may return the exhaustive display of the shortest path, for testing and verification.
For some reason, my IDE shows that BFS and Dijkstras has "duplicated code fragment 17 lines long" can someone look at tell me how to fix it or maybe a better way to implement it? Also, if i try to do nodesNum > 30k in "Driver Class" i get a memory leak.
Here is the code:
Class Graph:
import java.util.*;
import javax.swing.JOptionPane;
class Graph
{
private Listing[] vertex;
private int[][] edge;
private int max;
private int numberOfVertices;
private int nodeCheck = 0;
private int selectNum = 0;
Graph(int g)
{
vertex = new Listing[g];
edge = new int[g][g];
max = g;
numberOfVertices = 0;
}
private void depthFirstSearch(int firstVertex)
{
int v;
Stack<Integer> nodeStack = new Stack<>();
for(int i = 0; i<numberOfVertices; i++)
{
if (vertex[i] != null) {
vertex[i].setPushed(false);
}
}
nodeStack.push(firstVertex);
vertex[firstVertex].setPushed(true);
while (!nodeStack.empty())
{
v = nodeStack.pop();
vertex[v].visit();
nodeCheck++;
for (int column = 0; column < numberOfVertices; column++)
{
if(edge[v][column] == 1 && vertex[column].getPushed())
{
nodeStack.push(column);
vertex[column].setPushed(true);
}
}
}
}
private void breathFirstSearch(int firstVertex)
{
int V;
Queue<Integer> nodeQueue = new LinkedList<>();
for(int i = 0; i < numberOfVertices; i++)
{
if(vertex[i] != null)
vertex[i].setPushed(false);
}
nodeQueue.add(firstVertex);
vertex[firstVertex].setPushed(true);
while(!nodeQueue.isEmpty())
{
V = nodeQueue.remove();
vertex[V].visit();
nodeCheck++;
for(int column = 0; column < numberOfVertices; column++)
{
if(edge[V][column] == 1 && vertex[column].getPushed())
{
nodeQueue.add(column);
vertex[column].setPushed(true);
}
}
}
}
private void Dijkstra(int firstVertex)
{
int v;
LinkedList<Integer> nodeQueue = new LinkedList<>();
int i = 0;
while (i < numberOfVertices)
{
if(vertex[i] != null)
vertex[i].setPushed(false);
i++;
}
nodeQueue.add(firstVertex);
vertex[firstVertex].setPushed(true);
while(!nodeQueue.isEmpty())
{
v = nodeQueue.remove();
vertex[v].visit();
nodeCheck++;
for(int column = 0; column < numberOfVertices; column++)
{
if(edge[v][column] == 1 && vertex[column].getPushed())
{
nodeQueue.add(column);
vertex[column].setPushed(true);
}
}
}
}
private void insertVertex(int vertexNumber, Listing newListing)
{
if(vertexNumber >= max)
{
return;
}
vertex[vertexNumber] = newListing.deepCopy();
numberOfVertices++;
}
private void insertEdge(int fromVertex, int toVertex)
{
if(vertex[fromVertex] == null || vertex[toVertex] == null)
return;
edge[fromVertex][toVertex] = 1;
}
void showVertex(int vertexNumber)
{
System.out.print(vertex[vertexNumber]);
}
void showEdges(int vertexNumber)
{
for(int column = 0; column < numberOfVertices; column++)
{
if(edge[vertexNumber][column] == 1)
{
System.out.println(vertexNumber + "," + column);
}
}
System.out.println();
}
void InitializeNodes(Graph G, int nodesNum)
{
Random random = new Random();
for (int i = 0; i < nodesNum; i++ )
{
Listing v = new Listing(random.nextInt(300000) + 1);
G.insertVertex(i, v);
}
int vertexListNumber = G.vertex.length;
List<Integer> list = new ArrayList<>();
for (int i = 0; i < nodesNum; i++ )
{
list.add(i);
}
Collections.shuffle(list);
for (int i = 0; i < vertexListNumber; i++ )
{
int randnum = random.nextInt(5);
for (int j = 0; j < randnum; j++ )
{
int rand = random.nextInt(5);
G.insertEdge(i, list.get(rand));
}
}
}
int Search()
{
String search = JOptionPane.showInputDialog("Enter Node to search:");
try
{
if(search != null)
{
selectNum = Integer.parseInt(search);
}
}
catch (NumberFormatException e)
{
selectNum = 0;
}
return selectNum;
}
private int SelectPane()
{
String paneSelect = JOptionPane.showInputDialog("Choose a search method:" +
"\n\t1: Use Depth-First Search" +
"\n\t2: Use Breadth-First Search" +
"\n\t3: Use Dijkstra's Search" +
"\n\t4: Close Program");
int selectNum = 0;
try{
if(paneSelect != null)
{
selectNum = Integer.parseInt(paneSelect);
}
}
catch (NumberFormatException ignored)
{
}
return selectNum;
}
void algorithmChoice(Graph graph, int vertexStart)
{
int paneNum = 0;
while (paneNum != 4)
{
paneNum = SelectPane();
switch (paneNum)
{
case 1:
graph.depthFirstSearch(vertexStart);
System.out.println("Nodes counted were: " + nodeCheck);
System.out.println("------------------------------------");
break;
case 2:
graph.breathFirstSearch(vertexStart);
System.out.println("Nodes counted were: " + nodeCheck);
System.out.println("------------------------------------");
break;
case 3:
graph.Dijkstra(vertexStart);
System.out.println("Nodes counted were: " + nodeCheck);
System.out.println("------------------------------------");
break;
case 4:
break;
default:
JOptionPane.showMessageDialog(null, "Enter 4 to quit.");
break;
}
}
}
}
Class Listing:
public class Listing
{
private int value;
private boolean pushed;
Listing(int v)
{
value = v;
}
public String toString()
{
return ("Vertex: " + value + "\n" );
}
Listing deepCopy()
{
return new Listing(value);
}
boolean getPushed()
{
return !pushed;
}
void setPushed(boolean value)
{
pushed = value;
}
void visit()
{
System.out.println(this);
}
}
Class Driver:
public class Driver
{
public static void main(String[] args)
{
int nodesNum = 30000; //Can go up to 30k nodes, otherwise causes memory leak.
Graph graph = new Graph(nodesNum);
graph.InitializeNodes(graph, nodesNum);
for(int i = 0; i<5; i++)
{
System.out.print("Node " + i + "\'s ");
graph.showVertex(i);
System.out.print("Its routes are:\n");
graph.showEdges(i);
}
int select = graph.Search();
graph.algorithmChoice(graph, select);
}
}
Thanks alot for your help!
The error you get is due to exceeding max heap size when creating a edge = new int[g][g]; where g can be as high as 100,000 in your case.
I would suggest avoiding the use of such huge matrix.
Instead introduce an Edge object :
class Edge{
private final int fromVertex, toVertex;
Edge(int fromVertex, int toVertex){
this.fromVertex = fromVertex;
this.toVertex = toVertex;
}
#Override
public boolean equals(Object obj) {
if( ! (obj instanceof Edge)) return false;
Edge other = (Edge)obj;
return connects(other.fromVertex, other.toVertex);
}
boolean connects(int fromVertex, int toVertex){
return fromVertex == this.fromVertex && toVertex == this.toVertex ||
fromVertex == this.toVertex && toVertex == this.fromVertex;
}
}
and use it in Graph.
Instead of private int[][] edge; use a collection of Edges:
private final Set<Edge> edges = new HashSet<>();
Change insertEdge to:
private void insertEdge(int fromVertex, int toVertex)
{
if(vertex[fromVertex] == null || vertex[toVertex] == null)
return;
edges.add(new Edge(fromVertex, toVertex));
}
and add a method to check if there is an edge between two vertices:
private boolean isEdgeBetween(int fromVertex, int toVertex)
{
for(Edge edge : edges){
if(edge.connects(fromVertex, toVertex)) return true;
}
return false;
}
Usage : if( isEdgeBetween(v,column) && vertex[column].getPushed())
instead of: if(edge[v][column] == 1 && vertex[column].getPushed())

Problem in toString function in java (works with local variable)

i have a class in a java program where i am using a toString function to retrieve data. the toString checks a private function in the same class which returns a int value, for displaying different types of return messages.~
The problem is that if i use a local variable in the string function every turns out good, but if i check in the if statements directlly the private function, this function doesnt return any value.
private int computerTryHorizontalPlay() {
int repeatedMyValueCount = 0;
int repeatedYourValueCount = 0;
int[] myPositions = new int[3];
int[] yourPositions = new int[3];
for (int a = 0; a < 3; a++) {
int repeatedMyValue = 0;
int repeatedYourValue = 0;
int emptyFields = 0;
int[] emptyPosition = new int[2];
for (int b = 0; b < 3; b++) {
if (jogoGalo[a][b] == 'X') {
repeatedMyValue++;
} else if (jogoGalo[a][b] == 'O') {
repeatedYourValue++;
}
if (jogoGalo[a][b] == '-') {
emptyPosition[0] = a;
emptyPosition[1] = b;
emptyFields++;
}
}
if (repeatedMyValue == 3 || repeatedYourValue == 3) {
return 3;
} else {
if (emptyFields == 1) {
if (repeatedMyValue == 2) {
repeatedMyValueCount++;
myPositions[repeatedMyValueCount - 1] = emptyPosition[0];
myPositions[repeatedMyValueCount] = emptyPosition[1];
} else if (repeatedYourValue == 2) {
repeatedYourValueCount++;
yourPositions[repeatedYourValueCount - 1] = emptyPosition[0];
yourPositions[repeatedYourValueCount] = emptyPosition[1];
}
}
}
}
if (repeatedMyValueCount > 0) {
jogoGalo[myPositions[0]][myPositions[1]] = 'X';
return 2;
} else if (repeatedYourValueCount > 0) {
jogoGalo[yourPositions[0]][yourPositions[1]] = 'X';
return 1;
}
return 0;
}
This doesn´t work!
public String toString() {
if(computerTryHorizontalPlay() == 3) {
return "The game has already ended!";
}
else if(computerTryHorizontalPlay() == 2) {
return "Computer won!";
}
else if(computerTryHorizontalPlay() == 1) {
return "Computer defendeu!";
}
return null;
}
This works!
public String toString() {
int horizontalFunctionValue = computerTryHorizontalPlay();
if(horizontalFunctionValue == 3) {
return "The game has already ended!";
}
else if(horizontalFunctionValue == 2) {
return "Computer won!";
}
else if(horizontalFunctionValue == 1) {
return "Computer defendeu!";
}
return null;
}
}
toString() must be a read-only method, i.e. it is not allowed to have side-effects like changing the state of the object. Since computerTryHorizontalPlay() is a state-changing method, you are not allowed to call it from toString().
Since the only state-change happens in the last if statement, you can change the code to not execute the play when called from toString(), like this:
private int computerTryHorizontalPlay() {
return computerTryHorizontalPlay(true);
}
private int computerTryHorizontalPlay(boolean doMove) {
// lots of code here
if (repeatedMyValueCount > 0) {
if (doMove)
jogoGalo[myPositions[0]][myPositions[1]] = 'X';
return 2;
} else if (repeatedYourValueCount > 0) {
if (doMove)
jogoGalo[yourPositions[0]][yourPositions[1]] = 'X';
return 1;
}
return 0;
}
public String toString() {
if(computerTryHorizontalPlay(false) == 3) {
return "The game has already ended!";
}
else if(computerTryHorizontalPlay(false) == 2) {
return "Computer won!";
}
else if(computerTryHorizontalPlay(false) == 1) {
return "Computer defeated!";
}
return null;
}

Removing from a array and replacing the empty location

I have to create a public method called cancelPolicy(int polNum) which removes the policy from the client's list with the given policy number, if found. It should return true if the policy was found, otherwise it should return false. When a policy is removed from the array, the empty location in the array should be replaced by the last policy in the array.
The code I have written so far:
public int cancelPolicy(int polNum){
for (int i = 0; i < policies.length; i++) {
if (policies[i].getPolicyNumber() == polNum) {
}
}
return polNum;
}
What I don't understand is how to remove and replace from the array of policies[i].
This is precisely what you are looking for:
public boolean cancelPolicy(int polNum)
{
int n = policies.length-1; //optimization by making n = length-1
for (int i = 0; i <= n; i++) { //notice equals in condition
if (policies[i].getPolicyNumber() == polNum) {
policies[i] = policies[n]; //replace i with last if that's what you meant
policies[n] = null; //remove loitering
return true;
}
}
return false;
}
To replace the found policy, you need to do as follow:
public boolean cancelPolicy(int polNum){
for (int i = 0; i < policies.length; i++) {
if (policies[i].getPolicyNumber() == polNum) {
policies[i] = policies[arrSize - 1];
policies[arrSize - 1] = null;
arrSize--;
return true;
}
}
return false;
}
And in you class you need to keep the number of policies:
private int arrSize;
Alternatively you can recreate the array:
public boolean cancelPolicy(int polNum){
for (int i = 0; i < policies.length; i++) {
if (policies[i].getPolicyNumber() == polNum) {
int[] newArr = new int[policies.length - 1];
System.arraycopy(policies, 0, newArr , 0, i);
System.arraycopy(policies, i + 1, newArr, i, policies.length - i - 1);
policies = newArr;
return true;
}
}
return false;
}
And the best, but not sure if this option is available to you, would be to use a List or a Map
you cold get the last non null and then set the last element to null as well. this would "replace" it so you don't get duplicated policies. teachers like it when you think about stuff like that typically
public boolean cancelPolicy(int polNum){
for (int i = 0; i < policies.length; i++) {
if (policies[i].getPolicyNumber() == polNum) {
for (int j = policies.length - 1; j >=0; j--){
if (policies[j] != null) {
policies[i] = policies[j];
policies[j] = null;
return true;
}
}
}
}
return false;
}

What is the proper way to create a Hybrid Data structure of Ternary Search Trees

I am trying to create a class called HybridTST, where I can add multiple different TST's to a bigger data structure.
I have tried creating an array of Ternary Search Trees to a letter in the alphabet and then when I want to go to a specific TST I can iterate through the alphabet to find the correct TST. I am not sure if that the outcome is what I want. Am I creating a this Hybrid TST incorrectly?
public class HybridTST<E> implements TrieInterface
{
private TST[] myHybridTST = new TST[54];
private String alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.'";
private int position = 0;
private int size;
HybridTST()
{
char[] alphabetArray = alphabet.toCharArray();
for (int i = 0; i<54; i++)
{
myHybridTST[i]= new TST(alphabetArray[i]);
}
}
#Override
public Object get(String key) {
if (key == null) {
throw new InvalidKeyException();
}
for (int i = 0; i < key.length(); i++) {
if (!Character.isLetter(key.charAt(i))) {
throw new InvalidKeyException();
}
}
position = 0;
for(char c: alphabet.toCharArray())
{
if(key.charAt(0)==c)
{
break;
}
position++;
}
return myHybridTST[position].get(key);
}
Here is the TST get portion:
public Object get(String key) {
if (key == null) {
throw new InvalidKeyException();
}
if (key == null)
throw new NullPointerException();
if(key!="aren't")
{
for (int i = 0; i < key.length(); i++) {
if (!Character.isLetter(key.charAt(i))) {
throw new InvalidKeyException();
}
}
}
Node x = get(root, key, 0);
if (x == null) return null;
return x.val;
}
private Node get(Node x, String key, int d) {
if (key == null) {
throw new InvalidKeyException();
}
if (key.length() == 0)
throw new IllegalArgumentException("key must have length >= 1");
if (x == null)
return null;
char c = key.charAt(d);
if (c<x.c)
{
return get(x.left, key, d);
}
else if(c>x.c)
{
return get(x.right, key, d);
}
else if(d < key.length()-1)
{
return get(x.mid, key, d+1);
}
else
{
return x;
}
}
Here is the test:
public void test10()
{
HybridTST<Integer> t = new HybridTST<Integer>();
t.put("A",new Integer(0));
t.put("AB",new Integer(1));
t.put("ABC",new Integer(2));
assertEquals( new Integer(0), t.get("A") );
assertEquals( new Integer(1), t.get("AB") );
assertEquals( new Integer(2), t.get("ABC") );
}
It its failing to get any items that I have put into the data structure.
My Hybrid TST PUT method:
public void put(String key, Object val) {
if (key == null) {
throw new InvalidKeyException();
}
for (int i = 0; i <1; i++) {
if (!Character.isLetter(key.charAt(i))) {
throw new InvalidKeyException();
}
}
int count = 0;
int position = 0;
position = 0;
for(char c: alphabet.toCharArray())
{
if(key.charAt(0)==c)
{
break;
}
position++;
}
size++;
myHybridTST[position].put(key, val);
}
In my TST class,
private static class Node {
private char c; // character
private Node left, mid, right; // left, middle, and right
// subtries
private Object val; // value associated with string
public Node[] next;
Node(char c) {
this.c = c;
}
}
public TST(char c) {
this.root = new Node(c);
}
I have no problem running your code, inserting and fetching values from the tree. However, it can be improved in some way:
Remove unused attributes
Use generics so you force the type of the elements you insert and fetch from the HybridTST and TST
Indentation is sometimes off
The code doesn't work as is (Node doesn't have method visit)
Instead of getting the position of the first letter on the alphabet, create a helper method for that.
Instead of calling new Integer(i), use Integer.valueOf(i)
From what I can see, your code contains the attribute of a 256-way trie plus the one for a ternary search tree, you should clean it

Categories