View Full Version : [Java] Fusione di due array con ordinamento
Ecco un altro esercizio :(
Dati due array (ordinati), dare come output un nuovo array che contiene i due precedenti ordinati.
A prescindere che siano ordinati o meno la mia idea sarebbe stata di:
1) dare in input la prima serie di numeri
2) dare in input la seconda serie di numeri
3) creare un nuovo array fusione la cui lunghezza sia la somma dei due precedenti
5) un ciclo che copi tutto il primo array dalla posizione 0 del nuovo array fino alla lunghezza del primo array (se array è di 3 numeri da 0 a 2)
6)un altro ciclo che parta dalla prima posizione libera dell'array fusione (che secondo me è data dalla lunghezza totale del primo array+1) fino alla fine del secondo array
7) Utilizzare il bubble sort per ordinare il nuovo array
Il mio codice fa la fusione del primo ma del secondo array mi riporta solo un numero :mbe: del tipo primo array {9,8,7} e secondo array {6,5,4} il nuovo vettore che mi mostra è {9,8,7,0,4,0} :eek: :confused: :mc:
Dove ho sgarrato?
import javax.swing.*;
public class fusione {
public static void main (String[] args){
String lunghezza1 = JOptionPane.showInputDialog("Inserisci il numero di elementi del primo vettore");
int contatoreprimo = Integer.parseInt(lunghezza1);
int []vettore = new int [contatoreprimo];
for (int i=0;i<contatoreprimo;i++)
{
String k = JOptionPane.showInputDialog("Inserisci il numero"+(i+1));
int numeroprimo = Integer.parseInt(k);
vettore[i]= numeroprimo;
}
String lunghezza2 = JOptionPane.showInputDialog("Inserisci gli elementi del secondo vettore");
int contatoresecondo = Integer.parseInt(lunghezza2);
int [] vettore1 = new int [contatoresecondo];
for (int j=0;j<contatoresecondo;j++)
{
String h = JOptionPane.showInputDialog("Inserisci il numero"+(j+1));
int numerosecondo = Integer.parseInt(h);
vettore1[j]= numerosecondo;
}
int []vettorefusione = new int[vettore.length+vettore1.length];
int i =0;
while (i<vettore.length)
{
vettorefusione[i]=vettore[i];
i++;
}
int j = (vettore.length+1);
int appoggio=0;
while (appoggio<vettore1.length)
{
vettorefusione[j]=vettore1[appoggio];
appoggio++;
}
int cont1=0;
while (cont1<vettorefusione.length)
{
System.out.print(vettorefusione[cont1]);
cont1++;
}
}
}
Ps esiste anche arraycopy credo ma non so usarlo e vi chiedo un altro consiglio. Conviene a imparare anche il quicksort (che è più veloce e migliore) o anche se il bubble sort è lento va bene comunque in ogni caso?
Il mio è un corso di un anno sviluppo software e ci stanno riempiendo di nozioni
con un numero limitatissimo di ore e stiamo facendo di tutto (html, css, php,xml,java, script di linux) e sto facendo un po di confusione :help: quindi vorrei limitare al solo apprendimento di un algoritmo di ordinazione :doh:
franksisca
30-11-2007, 10:32
dalle api di java:
arraycopy(Object src, int srcPos, Object dest, int destPos, int length)
Copies an array from the specified source array, beginning at the specified position, to the specified position of the destination array.
naturalmente è un metodo della classe sistem, quindi si utilizza così:
Systemò.arraycopy(...)
impara il quick sort, serve sempre.....
Ok ma nel mio dove sta il problema?
franksisca
30-11-2007, 10:38
giusto...allora "I PROBLEMI" sono qui:
int []vettorefusione = new int[vettore.length+vettore1.length];
int i =0;
while (i<vettore.length)
{
vettorefusione=vettore[i];
i++;
}
[I] // old version int j = (vettore.length+1);
int j = (vettore.length);
int appoggio=0;
while (appoggio<vettore1.length)
{
// old version vettorefusione[j]=vettore1[appoggio];
vettorefusione[j+appoggio]=vettore1[appoggio];
appoggio++;
}
int cont1=0;
while (cont1<vettorefusione.length)
{
System.out.print(vettorefusione[cont1]);
cont1++;
}
}
}
e naturalmente manca l'ordinameto
franksisca
30-11-2007, 10:40
Ecco un altro esercizio :(
Dati due array (ordinati), dare come output un nuovo array che contiene i due precedenti ordinati.
secondo me, rileggendo questa traccia, devi creare il terzo array in modo diverso....
secondo me, rileggendo questa traccia, devi creare il terzo array in modo diverso....
Cioè?:confused:
franksisca
30-11-2007, 11:30
il fatto che i due array siano ordinati può voler dire 2 cose...oc he fai un controllo quando inserisci i singoli elementi negli array, oppure che "presupponi" che gli arrray sono ordinati e quindi ti avvantaggi nella costruzione del nuovo array.
pensa, se il primo array è [1,2,3] e il seondo è [4,5,6] la costruzione finale è array1+array2....semplice no???
questo lo puoi dire perchè i due arrray sono ordinati e il primo elemento del 2 vettore è più grande dell'ultimo del primo vettore.
ora, magari mi stoi flippando ioo, ma secondo me devi lavorare in questo senso, ovvero, prendi v1[0] e lo confronti con 2[0], se v10]<v2[0] allora in fusion[0] metti v1[0]....e così via.
ripeto, magari è un flip mio.....comunque quello coorretto funziona ;)
la mia soluzione:
public abstract class AbstractArray
{
protected int[] content;
protected void allocate(int length)
{
content = new int[length];
}
}
public abstract class AbstractInputArray extends AbstractArray
{
public AbstractInputArray(BufferedReader reader) throws NumberFormatException, IOException
{
allocate(readLength(reader));
readValues(reader);
sort();
}
private int readLength(BufferedReader reader) throws NumberFormatException, IOException
{
System.out.print("input " + this + " length: ");
return new Integer(reader.readLine());
}
private void readValues(BufferedReader reader) throws NumberFormatException, IOException
{
System.out.println("input " + this + " elements:");
for (int index = 0; index < content.length; index++)
{
content[index] = new Integer(reader.readLine());
}
}
private void sort()
{
Arrays.sort(content);
}
}
public class FirstArray extends AbstractInputArray
{
public FirstArray(BufferedReader reader) throws NumberFormatException, IOException
{
super(reader);
}
public String toString()
{
return "first array";
}
}
public class SecondArray extends AbstractInputArray
{
public SecondArray(BufferedReader reader) throws NumberFormatException, IOException
{
super(reader);
}
public String toString()
{
return "second array";
}
}
public class SequentialArray extends AbstractArray
{
private int index = 0;
public SequentialArray(AbstractArray source)
{
content = source.content;
}
public int getCurrentValue()
{
return content[index];
}
public int getNextValue()
{
return content[index++];
}
}
public class MergedArray extends AbstractArray
{
private SequentialArray firstArray;
private SequentialArray secondArray;
public MergedArray(AbstractArray firstArray, AbstractArray secondArray)
{
allocate(firstArray.content.length + secondArray.content.length);
this.firstArray = new SequentialArray(firstArray);
this.secondArray = new SequentialArray(secondArray);
for (int index = 0; index < content.length; index++)
{
content[index] = select();
}
}
private int select()
{
int firstValue;
try
{
firstValue = firstArray.getCurrentValue();
}
catch (IndexOutOfBoundsException e)
{
return secondArray.getNextValue();
}
int secondValue;
try
{
secondValue = secondArray.getCurrentValue();
}
catch (IndexOutOfBoundsException e)
{
return firstArray.getNextValue();
}
return selectValue(firstValue, secondValue);
}
private int selectValue(int firstValue, int secondValue)
{
if (firstValue < secondValue)
{
return firstArray.getNextValue();
}
else
{
return secondArray.getNextValue();
}
}
public String toString()
{
return "merged array";
}
public void print()
{
for (int value : content)
{
System.out.print(value + ", ");
}
System.out.println("end");
}
}
public class Test2
{
public static void main(String[] arguments) throws NumberFormatException, IOException
{
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
AbstractArray firstArray = new FirstArray(reader);
AbstractArray secondArray = new SecondArray(reader);
MergedArray mergedArray = new MergedArray(firstArray, secondArray);
System.out.print("thank you. " + mergedArray + ": ");
mergedArray.print();
}
}
scusate, so di aver esagerato ma che ci volete fare, sono un diamondcrushiano :asd:
Hai un po esagerato :confused: parecchie cose non le conosco neanche
Alla fine ho fatto così ma non so perchè il codice mio non funzionasse , poi provo a fare anche come aveva detto franciska con la sua interpretazione dell'esercizio
import javax.swing.*;
public class fusione {
static void swap(int a[], int primo, int secondo)
{
int tmp;
tmp = a[primo];
a[primo] = a[secondo];
a[secondo] = tmp;
}
static void bubblesort (int array [])
{
for (int pass=1; pass<array.length;pass++)
for (int pass1=0;pass1<array.length-1;pass1++)
if (array[pass1]>array[pass1+1])
swap (array,pass1,pass1+1);
}
public static void main (String[] args){
String lunghezza1 = JOptionPane.showInputDialog("Inserisci il numero di elementi del primo vettore");
int contatoreprimo = Integer.parseInt(lunghezza1);
int []vettore = new int [contatoreprimo];
for (int i=0;i<contatoreprimo;i++)
{
String k = JOptionPane.showInputDialog("Inserisci il numero"+(i+1));
int numeroprimo = Integer.parseInt(k);
vettore[i]= numeroprimo;
}
String lunghezza2 = JOptionPane.showInputDialog("Inserisci gli elementi del secondo vettore");
int contatoresecondo = Integer.parseInt(lunghezza2);
int [] vettore1 = new int [contatoresecondo];
for (int j=0;j<contatoresecondo;j++)
{
String h = JOptionPane.showInputDialog("Inserisci il numero"+(j+1));
int numerosecondo = Integer.parseInt(h);
vettore1[j]= numerosecondo;
}
int []vettorefusione = new int[vettore.length+vettore1.length];
int i =0;
while (i<vettore.length)
{
vettorefusione[i]=vettore[i];
i++;
}
int j = (vettore.length);
int appoggio=0;
while (appoggio<vettore1.length)
{
vettorefusione[j+appoggio]=vettore1[appoggio];
appoggio++;
}
int cont1=0;
bubblesort(vettorefusione);
while (cont1<vettorefusione.length)
{
System.out.print(vettorefusione[cont1]+"\t");
System.out.println ();
cont1++;
}
}
}
Hai un po esagerato :confused: parecchie cose non le conosco neanche mavalà, sono praticamente dei POJO :D
mavalà, sono praticamente dei POJO :D
Ah be potevi dirlo primo ora si che è più chiaro :D
Una domanda: io ho eclipse alla 3.3.1.1 posso mettere la lingua italiana usando il language pack della 3.2 dato che porta solo quello?
Ah be potevi dirlo primo ora si che è più chiaro :D http://en.wikipedia.org/wiki/Plain_Old_Java_Object
intendevo dire che il design è semplicerrimo: il codice è distribuito in tanti metodi distribuiti a loro volta in tante classi, e ciascun metodo ha complessità molto bassa. su Diamond Crush lavoravamo sempre così (sigh, che bei ricordi :cry: a proposito, mi sa tanto che non si riparte manco stavolta :asd: ma non c'è problema, io ho trovato ben altro da fare :D :D :D)
franksisca
30-11-2007, 15:16
Hai un po esagerato :confused: parecchie cose non le conosco neanche
Alla fine ho fatto così ma non so perchè il codice mio non funzionasse , poi provo a fare anche come aveva detto franciska con la sua interpretazione dell'esercizio
....ma guarda che io l'ho scritto perchè non funziona....
....ma guarda che io l'ho scritto perchè non funziona....
Si lo so che il mio non funzionava è che volevo capire dove ho sbagliato. Ho fatto come hai detto tu e infatti funziona.
Mi riferivo piuttosto alla questione di inserire una if quando faccio la fusione
franksisca
30-11-2007, 15:56
tu avevi sbagliato le parti commentate vicino a quelle in grassetto.....
il discorso di inserire un if è una mia supposizione, non sò se devi farla o se va bene come stai facendo tu....
qwerty86
30-11-2007, 17:19
RedVex secondo me è sbagliato l'approccio , tu ordini qualcosa che è già ordinato , non sfruttando il fatto che i due array sono ordinati . Da quello che so io bisogna confrontare i primi due elementi dei primo e del secondo array e inserire il più piccolo nell'array Fusione , e incrementare l'indice dell'array che aveva l'elemento più piccolo , ( se l'elemento + piccolo era quello del primo array ) si confronta il secondo elemento del primo array col primo elemento del secondo array e così via. Alla fine se uno dei due array finisce prima ( significa che i due array avevano dimensione diversa) allora si copia l'array restante nell'array Fusione. Non so se sono stato chiaro. :)
RedVex secondo me è sbagliato l'approccio , tu ordini qualcosa che è già ordinato , non sfruttando il fatto che i due array sono ordinati . Da quello che so io bisogna confrontare i primi due elementi dei primo e del secondo array e inserire il più piccolo nell'array Fusione , e incrementare l'indice dell'array che aveva l'elemento più piccolo , ( se l'elemento + piccolo era quello del primo array ) si confronta il secondo elemento del primo array col primo elemento del secondo array e così via. Alla fine se uno dei due array finisce prima ( significa che i due array avevano dimensione diversa) allora si copia l'array restante nell'array Fusione. Non so se sono stato chiaro. :)
Si ho capito ma in questo caso funziona meglio perchè si possono anche non inserire ordinati poi bo.
qwerty86
30-11-2007, 17:28
Come ho detto io li inserisci ordinati perchè sfrutti proprio l'ordinamento dei due vettori iniziali :)
Questa è una classe che fonde due array ordinati (devono essere già ordinati come richiede l'esercizio)
public class ArraysMerger {
private int[] firstOrderedArray;
private int[] secondOrderedArray;
private int[] result = null;
private int firstCurrent;
private int secondCurrent;
private int current;
public ArraysMerger(int[] firstArray, int[] secondArray) throws IllegalArgumentException{
try {
this.firstOrderedArray = firstArray;
this.secondOrderedArray = secondArray;
result = new int[resultLength()];
}
catch(NullPointerException ex){
throw new IllegalArgumentException();
}
}
public int[] merge(){
firstCurrent = 0;
secondCurrent = 0;
current = 0;
while(noArrayCompleted()) {
if(firstOrderedArray[firstCurrent] <= secondOrderedArray[secondCurrent])
result[current++] = firstOrderedArray[firstCurrent++];
else
result[current++] = secondOrderedArray[secondCurrent++];
}
fill(firstCurrent,firstOrderedArray);
fill(secondCurrent,secondOrderedArray);
return result;
}
// helpers methods
private int resultLength(){
return firstOrderedArray.length + secondOrderedArray.length;
}
private boolean noArrayCompleted(){
return firstCurrent < firstOrderedArray.length &&
secondCurrent < secondOrderedArray.length;
}
private void fill(int c, int[] array) {
if (c < array.length) {
while (c < array.length) {
result[current++] = array[c++];
}
}
}
}
per usarla crei un oggetto di tipo ArraysMerger passandogli i due array da fondere poi richiami il metodo merge che restituisce l'array ordinato ottenuto dalla fusione dei due.
Mi pare che funzioni
qwerty86
30-11-2007, 17:43
Ragazzi credo che gli esercizi servono a far lavorare un pò la testa , a che serve utilizzare delle funzioni predefinite??
si puo imparare anche leggendo il codice.
sta a lui decidere se controllarla e capirne il funzionamento (anche perchè potrebbe essere sbagliata), oppure copiarla e fidarsi di me per fare l'esercizio.
Non la farò perchè son cose che ancora non conosco così mi affido a quello che so ^^ Già la bubble sort è abbastanza complicata per me :D
Allora prova a reimpostare l'esercizio come ti ha detto qwerty86 perchè non stai facendo quello che ti chiede.
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.