Passing an array of object from one class to another - object

I've been trying to create a program where it takes an array input through an object and passes the parameter (simulation of ArrayList).
I keep getting the java.lang.ArrayIndexOutOfBoundsException in which I'm guessing I'm not accessing the array properly..
What can I do to enhance the test object and/ or the constructor?
public class MyArrayList{
public int[] x;
public MyArrayList( ){
x = new int[0];
}
public MyArrayList(int[] k)
{
for (int i = 0; i < x.length; i++)
x[i] = k[i];
k = x;
}
public void add(int index).......
public int size().....
public int get(int index).....
public void set(int index, int value).......
public String toString( )........
Below is the class I am having trouble with.
public class TestMyArrayList
{
public static void main(String[] args)
{
MyArrayList test = new MyArrayList();
test.x[0] = 1;
test.x[1] = 2;
test.x[2] = 3;
test.x[3] = 4;
test.x[4] = 5;
test.add(2);
test.set(1,3);
int a, b;
String c;
a = test.size( );
b = test.get(5);
c = test.toString( );
System.out.println("The size of the array is" + a);
System.out.println("The value at that position is " + b);
System.out.println("The resulting string is: " + c);
}
}

This line from your constructor is the only location (in the code you've shown) where the array x is initialized:
x = new int[0];
And it creates a zero length array. Assuming you are not reinitializing the array somewhere else then all these lines will definitely fail:
test.x[0] = 1;
test.x[1] = 2;
test.x[2] = 3;
test.x[3] = 4;
test.x[4] = 5;
Because your array length is zero. So:
Initialize your array to a more sensible value
Consider encapsulating the array so that callers cannot directly access it. This will make it much easier to code up your application in the long run
Side note (aka bonus):
This other constructor of yours:
public MyArrayList(int[] k) {
for (int i = 0; i < x.length; i++)
x[i] = k[i];
k = x;
}
has some issues as well:
You should reinitialize your array x to be the same size as the supplied array, prior to copying over the values.
The assignment k = x is basically a no-op, because it doesn't actually change what k was pointing to outside of the method.
Overall, it should look more like this:
public MyArrayList(int[] k) {
super();
if(k != null) {
x = new int[k.length];
for (int i = 0; i < x.length; i++) {
x[i] = k[i];
}
} else {
x = null;
}
}

Related

issues with Optimizing Speed and Strings

How can I optimize the processing of strings?
Your problem is you are making n copies of t and concatenating them. This is a simple approach, but quite expensive - it turns what could be an O(n) solution into an O(n2) one.
Instead, just check each char of s:
for (int i = 0; i < s.length(); i++) {
if (s.charAt(i) != t.charAt(i % t.length())) {
return -1:
}
}
Do not make new strings, but use String.regionMatches.
Use String.length and modulo % == 0.
The smallest substring of t can be done using the same method.
Coding:
new String(string) ist never needed.
String += is slow. Better use StringBuilder.
No code to not spoil your coding.
Just a remark:
in general working with char[] is much faster than working with String.
(but nowhere near as convenient)
And make your variables final when they are final.
(it makes no difference to performance, but aids understanding)
Anyway, this might do it:
import java.util.Arrays;
class Result {
public static int findSmallestDivisor(final String s, final String t) {
final int lenS = s.length();
final int lenT = t.length();
/*
* Get Length & Chars of shortest & longest Strings...
*/
final int lenShort;
final int lenLong;
final char[] charsShort;
final char[] charsLong;
if (lenS < lenT) {
lenShort = lenS; charsShort = s.toCharArray();
lenLong = lenT; charsLong = t.toCharArray();
} else {
lenShort = lenT; charsShort = t.toCharArray();
lenLong = lenS; charsLong = s.toCharArray();
}
/*
* Get the Factor & exit if there's a remainder...
*/
final int factor = lenLong / lenShort;
final int factorRem = lenLong % lenShort;
if (factorRem != 0) {
return -1;
}
/*
* Try all possible divisors...
*/
for (int d=1; d <= lenShort; d++) {
final int n = lenShort / d;
final int nRem = lenShort % d;
if (nRem != 0) {
continue;
}
final char[] dChars = Arrays.copyOf(charsShort, d);
final char[] dCharsMultipliedShort = multiplyChars(dChars, n);
final char[] dCharsMultipliedLong = multiplyChars(dCharsMultipliedShort, factor);
if (Arrays.equals(charsShort, dCharsMultipliedShort)
&& Arrays.equals(charsLong, dCharsMultipliedLong )) {
return d;
}
}
return -1;
}
private static char[] multiplyChars(final char[] a, final int n) {
// if (n == 0) { // Necessary: otherwise ArrayIndexOutOfBoundsException in getChars(...)
// return new char[] {}; // (n is never 0)
// }
if (n == 1) { // Optional: optimisation
return a;
}
final int aLength = a.length;
final char[] charsMultiplied = new char[aLength * n];
System.arraycopy(a, 0, charsMultiplied, 0, aLength); // Fill in 1st occurrence
/*
* Copy 1st occurrence to the remaining occurrences...
*/
for (int i = 1; i < n; i++) {
System.arraycopy(charsMultiplied, 0, charsMultiplied, i*aLength, aLength);
}
return charsMultiplied;
}
}

C# Lock implement goes wrong

I try to make a lock on the incrementer "counter" in the Countrange method.
The counter should count under some conditions in the threads. If I complete the threads in order (not parallel) i get the right counter value over and over, but when i try to lock like i do in de program, it still isn't threadsafe, because i get diffrent counter values when i run the program a few times.
{
class Program
{
static int e, p, b, m;
static int counter = 0;
static int lok = 0;
static void Main(string[] args)
{
string input = Console.ReadLine();
string[] inputs = input.Split(' ');
counter = 0;
p = Convert.ToInt32(inputs[4]);
e = Convert.ToInt32(inputs[2]);
b = Convert.ToInt32(inputs[1]);
m = Convert.ToInt32(inputs[3]);
Thread[] ts = new Thread[p];
for (int t = 0; t < p; t++)
{
ts[t] = new Thread(countrange);
}
for (int t = 0; t < p; t++)
{
ts[t].Start(t);
}
for (int t = 0; t < p; t++)
{
ts[t].Join();
}
Console.Write(counter);
//Console.ReadKey();
}
public static void countrange(object mt)
{
int to = eind * (((int)mt + 1) / p) + verdeler + b;
int from = eind * (((int)mt) / p) + verdeler - a + b;
for (int i = from; i < to; i++)
{
proef = proef + moduler * keer;
}
{
if (proef % m == 0)
lock (mt)
{
counter++;
}
}
}
}
}
}
I made the lock static, now it works

How is a JPEG file formated?

I'm trying to write Bytes into a JPEG file, but I don't know the file's format and so the Bytes aren't in the right place of the image after writing into the file.
Does somebody know?
There are several markers that must appear in a JPEG file stream. I believe you can easily find the detailed description of the tags listed below on Internet.
SOI(0xFFD8) Start of Image
APP0(0xFFE0) Application
[APPn(0xFFEn)] (alternative)
DQT(0xFFDB) Define Quantization Table
SOF0(0xFFC0) Start of Frame
DHT(0xFFC4) Difine Huffman Table
SOS(0xFFDA) Start of Scan
DRI(0xFFDD) Define Restart Interval,(alternative)
...Image Stream
EOI(0xFFD9) End of Image
Those markers are followed by lengths in BIG ENDIAN format. You can decode Image Stream that exactly follows DRI using the huffman trees you decoded by DQT. For easier illustration, here are some functions I have written on my own in Java that decodes a header of JPEG, but without doubt there are many better JPEG Java projects on Github that you can refer to.
public int[][] cutX(byte[] x){
int s = x.length;int k = 1;int i = 2;int j;
d2[0][0]=Tool.unsignDecoder(x[1]);d2[1][0]=0;d2[2][0]=1;
while(d2[0][k-1]!=218){
d2[1][k]=i;
d2[0][k]=Tool.unsignDecoder(x[i+1]);
i=i+2+Tool.unsignDecoder(x[i+2])*256+Tool.unsignDecoder(x[i+3]);
d2[2][k]=i-1;
k=k+1;
}
for (j=s-1;j<i;j--){
if((Tool.unsignDecoder(x[j-1])==255)&&(Tool.unsignDecoder(x[j])==217)) break;
}
d2[0][k]=217;d2[1][k]=i;d2[2][k]=j+1;
return d2;
}
public void cutdata(byte[] x,int[][] d){
int a =Tool.indexOf_1(d[0],218);
int b =Tool.indexOf_1(d[0],217);
head = Arrays.copyOfRange(x, 0, d[2][a]+1);
byte[] im = Arrays.copyOfRange(x, d[1][b], d[2][b]-1);//-2:delete the last EOI message.
im1 = new byte[im.length];
int j=0;int i=0;//dynamically record the length of the revised sequence
while(i<im.length){
im1[j]=im[i];
j++;
if((i!=im.length-1)&&(Tool.unsignDecoder(im[i])==255)&&(Tool.unsignDecoder(im[i+1]))==0){
i++;//move rightward i
}
i++;
}
im1=Arrays.copyOfRange(im1, 0, j);//delete zeros in the end of the sequence
}
public void sof(byte[] x,int[][] d){
int z = Tool.indexOf_1(d[0],192);
int i = d[1][z];
int[] temp = new int[19];
for(int j=0;j<19;j++){
temp[j]=Tool.unsignDecoder(x[j+i]);
}
int ph=i+5;int pw=i+7;
size[0] = Tool.unsignDecoder(x[ph])*256+Tool.unsignDecoder(x[ph+1]);
size[1] = Tool.unsignDecoder(x[pw])*256+Tool.unsignDecoder(x[pw+1]);
i += 11;//skip some unused letters
for(int j=0;j<3;j++){
int k = Tool.unsignDecoder(x[i]);
Q[j][0] = (k & 0xF0)/16;
Q[j][1] = k & 0x0F;
i += 3;
}
}
public void hfm(byte[] x,int[][] d){
//the DHT marker may appear several times in a JPEG, or several huffman trees can be found in a single DHT.
ArrayList res =Tool.indexOf(d[0],196);int thisLength;int pointer;int pointerOrigin;
int a;int huffLength = 0;
for(int z=0;z<res.size();z++){
a=(int) res.get(z);
pointer = d[1][a];pointerOrigin = d[1][a]+2;//please follow the straight-forward moving of this pointer
thisLength = Tool.unsignDecoder(x[pointer+2])*256+Tool.unsignDecoder(x[pointer+3]);
int[] temp = new int[thisLength+4];
for(int i=0;i<thisLength;i++){
temp[i]=Tool.unsignDecoder(x[pointer+i]);
}
pointer += 4;
while(huffLength<thisLength){
int mode = Tool.unsignDecoder(x[pointer]);pointer += 1;
int[] huff_num = new int[16];int total=0;
for(int i=0;i<16;i++){//码字总个数
huff_num[i] = x[pointer+i];total+=huff_num[i];
}
pointer +=16;int codePointer=0;int code=0;
int[][] huffmanTree = new int[3][total];
for(int i=0;i<16;i++){
if(i!=0){
code *= 2;
}
for(int j=0;j<huff_num[i];j++){
huffmanTree[0][codePointer]=i+1;
huffmanTree[1][codePointer]=code;
huffmanTree[2][codePointer]=Tool.unsignDecoder(x[pointer+codePointer]);
code++;codePointer++;
}
}
huffLength += pointer + codePointer - pointerOrigin;pointer += codePointer;
pointerOrigin = pointer;
switch(mode){
case(0):d0 = huffmanTree;break;
case(1):d1 = huffmanTree;break;
case(16):a0 = huffmanTree;break;
case(17):a1 = huffmanTree;break;
}
}
}
}
public void dri(byte[] x,int[][] d){
int z = Tool.indexOf_1(d[0],221);
if(z!=-1){
int pointer = d[1][z];
int len = Tool.unsignDecoder(x[pointer+2])*256+Tool.unsignDecoder(x[pointer+3]);
int[] temp = new int[len+2];
for(int i=0;i<len;i++){
temp[i]=Tool.unsignDecoder(x[pointer+i]);
}
DRI = Tool.unsignDecoder(x[d[1][z]+4])*256+Tool.unsignDecoder(x[d[1][z]+5]);}
}
public void sos(byte[] x,int[][] d){
int z = Tool.indexOf_1(d[0],218);int a = d[1][z];
int len = Tool.unsignDecoder(x[a+2])*256+Tool.unsignDecoder(x[a+3]);
int[] temp = new int[len+2];
for(int j=0;j<len+2;j++){
temp[j]=Tool.unsignDecoder(x[j+a]);
}
int pointer = d[1][z]+6;
for(int j=0;j<3;j++){
treeSelect[j] = Tool.unsignDecoder(x[pointer]);
pointer += 2;
}
}

Why is if-else for String faster than switch-case for enum?

As Java 6 does not have switch-case for String, I often change an if-else block to switch-case using enum as in the code below. However, when I tried to check the performance of the two alternatives, I found that switch-case to be slower than the if-else alternative, contrary to what I had expected. Here are some of the results that I got for the code below
Iterations If-Else Switch-Case
1 11810 1609181
10 8214 1059115
100 24141 1152494
1000 183975 1580605
10000 4452698 8710648
100000 7069243 19457585
package conditionals;
import java.util.Random;
public class StringConditionalCheck {
private static int ifElseCounter = 0;
private static int switchCaseCounter = 0;
private static final String first = "First";
private static final String second = "Second";
private static final String third = "Third";
private static final String fourth = "Fourth";
enum StringOptions {
First, Second, Third, Fourth
}
public static void main(String[] args) {
final int iterations = Integer.parseInt(args[0]);
String[] userInputs = generateUserInputs(iterations);
// Using if-else
long ifelseStartTime = System.nanoTime();
for(int i=0; i<iterations; i++){
useIfElse(userInputs[i]);
}
long ifelseEndTime = System.nanoTime();
long ifElseDuration = ifelseEndTime - ifelseStartTime;
long switchcaseStartTime = System.nanoTime();
for(int i=0; i<iterations; i++){
useSwitchCase(userInputs[i]);
}
long switchcaseEndTime = System.nanoTime();
//just to verify that both options had the same result.
long switchcaseDuration = switchcaseEndTime - switchcaseStartTime;
System.out.println(iterations + " " + ifElseDuration + " " + switchcaseDuration + " " + ifElseCounter + " " + switchCaseCounter);
}
private static String[] generateUserInputs(int numberOfInputs) {
String[] generatedInputs = new String[numberOfInputs];
String[] inputsToChooseFrom = new String[]{first, second, third, fourth};
Random r = new Random();
for (int i = 0; i < numberOfInputs; i++) {
int choice = r.nextInt(4);
generatedInputs[i] = inputsToChooseFrom[choice];
}
return generatedInputs;
}
public static void useSwitchCase(String input) {
StringOptions option = StringOptions.valueOf(input);
switch(option){
case First:
switchCaseCounter += 1;
break;
case Second:
switchCaseCounter += 2;
break;
case Third:
switchCaseCounter += 3;
break;
case Fourth:
switchCaseCounter += 4;
break;
}
}
public static void useIfElse(String input) {
if(input.equals("First")){
ifElseCounter += 1;
}else if(input.equals("Second")){
ifElseCounter += 2;
}else if(input.equals("Third")){
ifElseCounter += 3;
}else if(input.equals("Fourth")){
ifElseCounter += 4;
}
}
}
What is the cause for this difference? I was expecting that if-else would be slower as there will be more comparisons on average.
Because 99% of your time is being spent in StringOptions option = StringOptions.valueOf(input);, not in the switch
Based on the source code, the StringOptions.valueOf call does several complicated things, including building a HashMap every call, whereas String.equals simply loops through the string once.
Compare the source code for Enum.valueOf (which calls Enum.getConstantDirectory) to String.equals.

ReadLine - Array index out of bounds

I have been debugging this program to find the error but couldn't succeed in that. For some reason, it is displaying an error - array index out of bounds in this line
moves[nCount].sDirection = sStep[0]; I know, this forum is not meant for debugging, im sorry for that.
class Program
{
struct move
{
public char sDirection;
public int steps;
}
static void Main(string[] args)
{
int nNumOfInstructions = 0;
int nStartX = 0, nStartY = 0;
move[] moves = new move[nNumOfInstructions];
nNumOfInstructions=Convert.ToInt32(Console.ReadLine());
string sPosCoOrd = Console.ReadLine();
nStartX = Convert.ToInt32(sPosCoOrd[0]);
nStartY = Convert.ToInt32(sPosCoOrd[2]);
string sStep = "";
for (int nCount = 0; nCount < nNumOfInstructions; nCount++)
{
sStep = Console.ReadLine();
int length = sStep.Length;
moves[nCount].sDirection = sStep[0];
moves[nCount].steps = Convert.ToInt32(sStep[1]);
}
Console.ReadLine();
}
}
In your code, the moves array is created as an array of zero length. For any index, accessing this array will inevitably throw an Array index out of bounds
You probably want to do it this way:
class Program
{
struct move
{
public char sDirection;
public int steps;
}
static void Main(string[] args)
{
int nNumOfInstructions = Convert.ToInt32(Console.ReadLine());
move[] moves = new move[nNumOfInstructions];
string sPosCoOrd = Console.ReadLine();
int nStartX = Convert.ToInt32(sPosCoOrd[0]);
int nStartY = Convert.ToInt32(sPosCoOrd[2]);
string sStep = String.Empty;
for (int nCount = 0; nCount < nNumOfInstructions; nCount++)
{
sStep = Console.ReadLine();
int length = sStep.Length;
moves[nCount].sDirection = sStep[0];
moves[nCount].steps = Convert.ToInt32(sStep[1]);
}
}
}

Resources