Related
I have int 2-5 arrays (user decision how much), each of which has its own elements. I need to compare them to print their names.
For example, I have 3 arrays, First contains: 3, 41, 315, 2. Second contains: 5, 31, 315. The Third one contains: 315, 41, 3, 2, 2, 41. How can I compare their elements, to print names of the arrays that have the same elements, like this: ("FIRST THIRD").
(They can be in or out of order, and they can repeat);**
I tried to play with indexes of arrays, if array1[0] == array2[0], then compare other elements, but it will take a while to write this all, and it will take a lot of space, maybe there is a cleaner fix for this?
#define N 6
int arr1[N] = { 3, 41, 315, 2 }, arr2[N] = { 5, 31, 315 }, arr3[N] = {315, 41, 3, 2, 2, 41};
for (int h = 0; h <= N; h++)
if (arr1[j] == arr2[h])
{
// compare other elements of arrays one by one adding indexes of arrays
}
}
I want it to output :
First Third
Performance isn't great, but you can define a function contained_in that checks to see if everything in one array is in another.
int contained_in(int *arr1, size_t n1, int *arr2, size_t n2) {
for (size_t i = 0; i < n1; i++) {
int contained = 0;
for (size_t j = 0; j < n2 && !contained; j++) {
if (arr1[i] == arr2[j]) {
contained = 1;
}
}
if (!contained) return 0;
}
return 1;
}
If you check contained_in(arrascii1, N, arrascii2, N) and contained_in(arrascii2, N, arrascii1, N) then you'll know that both contain the same values.
Instead of defining the arrays arr1, arr2 and arr3 as separate arrays, it would probably be easier to define an array of arrays, for example like this:
#define NUM_ARRAYS 3
#define N 6
int arrays[NUM_ARRAYS][N] = {
{ 3, 41, 315, 2 },
{ 5, 31, 315 },
{ 315, 41, 3, 2, 2, 41}
};
That way you can use the indexes of both dimensions in loops, which will make the coding easier:
#include <stdio.h>
#include <stdbool.h>
#define NUM_ARRAYS 3
#define N 6
//This function returns true if the right array contains all
//elements of the left array, and vice versa. Otherwise it returns false.
bool compare_arrays( int left[], int right[] )
{
//check whether right array contains all elements in the
//left array
for ( int i = 0; i < N; i++ )
{
for ( int j = 0; ; j++ )
{
if ( j == N )
return false;
if ( left[i] == right[j] )
break;
}
}
//check whether left array contains all elements in the
//right array
for ( int i = 0; i < N; i++ )
{
for ( int j = 0; ; j++ )
{
if ( j == N )
return false;
if ( right[i] == left[j] )
break;
}
}
return true;
}
int main( void )
{
const char *map[] = {
"First", "Second", "Third", "Fourth", "Fifth",
"Sixth", "Sevent", "Eighth", "Ninth", "Tenth"
};
int arrays[NUM_ARRAYS][N] = {
{ 3, 41, 315, 2 },
{ 5, 31, 315 },
{ 315, 41, 3, 2, 2, 41 }
};
for ( int i = 0; i < NUM_ARRAYS; i++ )
{
for ( int j = i + 1; j < NUM_ARRAYS; j++ )
{
if ( compare_arrays( arrays[i], arrays[j] ) )
printf( "%s %s\n", map[i], map[j] );
}
}
}
However, this program has no output. That is because the array arr1 also contains the value 0 in its last two elements, which do not exist in arr3. Therefore, the comparison of arr1 and arr3 fails.
The reason why the value of the last two elements is 0 is because if at least one element of the array is initialized, then all elements that are not explicitly initialized are implicitly initialized to 0.
For the reasons stated above, it would be appropriate to have an additional variable for every array, which specifies the number of valid elements in the array. Instead of using separate variables, it would probably be better to group them with the array in a struct:
struct array_with_length
{
int length;
int array[N];
};
That way, you can limit the loops to the number of valid elements:
#include <stdio.h>
#include <stdbool.h>
#define NUM_ARRAYS 3
#define N 6
struct array_with_length
{
int length;
int array[N];
};
//This function returns true if the right array contains all
//elements of the left array, and vice versa. Otherwise it returns false.
bool compare_arrays(
const struct array_with_length *left,
const struct array_with_length *right
)
{
//check whether right array contains all elements in the
//left array
for ( int i = 0; i < left->length; i++ )
{
for ( int j = 0; ; j++ )
{
if ( j == right->length )
return false;
if ( left->array[i] == right->array[j] )
break;
}
}
//check whether left array contains all elements in the
//right array
for ( int i = 0; i < right->length; i++ )
{
for ( int j = 0; ; j++ )
{
if ( j == left->length )
return false;
if ( right->array[i] == left->array[j] )
break;
}
}
return true;
}
int main( void )
{
const char *map[] = {
"First", "Second", "Third", "Fourth", "Fifth",
"Sixth", "Sevent", "Eighth", "Ninth", "Tenth"
};
struct array_with_length arrays[NUM_ARRAYS] = {
{
4, //number of elements in array
{ 3, 41, 315, 2 }, //array content
},
{
3, //number of elements in array
{ 5, 31, 315 }, //array content
},
{
6, //number of elements in array
{ 315, 41, 3, 2, 2, 41 } //array content
}
};
for ( int i = 0; i < NUM_ARRAYS; i++ )
{
for ( int j = i + 1; j < NUM_ARRAYS; j++ )
{
if ( compare_arrays( &arrays[i], &arrays[j] ) )
printf( "%s %s\n", map[i], map[j] );
}
}
}
This program has the following output:
First Third
This is the output that you said that you wanted.
I have a question about 2 dimensional array in GoLang. I do not know why the sort method I use does not work, but It works well in java, C, and C++, but I am not sure what is wrong when I applied the same sort method in Golang, sometimes it give me the right result, sometimes, it does not sort at all. Please help. Thank you so much in advance.
package main
import (
"fmt"
)
var employee int = 0
var day int = 1
func main() {
list := [][] int {{2, 4, 3, 4, 5, 8, 8},
{7, 3, 4, 3, 3, 4, 4},
{3, 3, 4, 3, 3, 2, 2},
{9, 3, 4, 7, 3, 4, 1},
{3, 5, 4, 3, 6, 3, 8},
{3, 4, 4, 6, 3, 4, 4},
{3, 7, 4, 8, 3, 8, 4},
{6, 3, 5, 9, 2, 7, 9}}
var result [8][2] int
for i := 0; i < len(result); i++ {
var total int = 0
for j := 0; j < len(list[i]); j++ {
total += list[i][j]
}
result[i][employee] = i
result[i][day] = total
}
sort(result)
fmt.Println("The decreasing order is:")
for i := 0; i < len(result); i++ {
fmt.Printf("Employee %v's total dayoff is %v\n", result[i][employee], result[i][day])
}
}
func sort(list[8][2] int) {
for i := 0; i < len(list); i++ {
var max_day int = list[i][day]
var max_employee int = list[i][employee]
var max_index int = i
for j := i + 1; j < len(list); j++ {
if list[j][day] > max_day {
max_day = list[j][day]
max_employee = list[j][employee]
max_index = j
}
}
if max_index != i {
list[max_index][employee] = list[i][employee]
list[max_index][day] = list[i][day]
list[i][employee] = max_employee
list[i][day] = max_day
}
}
}
You're modifying a copy of list in your sort() function, change its prototype to:
func sort(list *[8][2]int) {
and call it:
sort(&result)
Why am I getting index out of range in mat[i][j] = matrix[i+1][j+1]?
On the functions below I'm trying to count the determiner of a matrix.
Function eraze is to erase one line and one column so when I am filling the new matrix (array). Exception shows 'index out of range'.
func det2(matrix :[[Int]] ) -> Int {
var p : Int
p = matrix[0][0] * matrix[1][1] - matrix[0][1] * matrix[1][0]
return p
}
func det(matrix :[[Int]] , fo : Int ) -> Int {
var p2 : Int = 0
if (fo == 2) {
p2 = det2(matrix: matrix)
} else {
for j in 0..<fo {
p2 = matrix[j][0] * det(matrix: eraze(matrix: matrix, nb: j, dim: fo), fo: fo-1)
}
}
return p2
}
func eraze(matrix : [[Int]] , nb: Int , dim : Int) -> [[Int]] {
var mat = [[Int]]()
for i in 0..<dim-1 {
for j in 0..<dim-1 {
if (i == nb ) || (i>nb) {
mat[i][j] = matrix[i+1][j+1]
} else if (i<nb) {
mat[i][j] = matrix[i][j+1]
}
}
}
return mat
}
Your first issue is that in eraze(), you aren't initializing mat. In Swift you can't index into an empty array.
Replace:
var mat = [[Int]]()
with:
var mat = [[Int]](repeating: Array(repeating: 0, count: dim - 1), count: dim - 1)
With that change, your code no longer crashes, but it produces incorrect results.
You forgot to sum up the values of the expansion and when you do that you need to alternate the sign of the values:
func det(matrix :[[Int]] , fo : Int ) -> Int {
func sign(_ n: Int) -> Int {
return n % 2 == 0 ? 1 : -1
}
var p2 : Int = 0
if (fo == 2) {
p2 = det2(matrix: matrix)
} else {
for j in 0..<fo {
p2 += (sign(j) * matrix[j][0] * det(matrix: eraze(matrix: matrix, nb: j, dim: fo), fo: fo-1))
}
}
return p2
}
Test
det(matrix: [[1, 4, 7, 3, -6], [2, 5, 8, 4, -3], [3, 6, 10, -5, 14], [1, -2, 3, 4, 5], [6, -5, 4, -3, 2]], fo: 5)
13090
which agrees with Wolfram Alpha
How could I make this go program recursive. I'm learning golang by writing a game number analyzer. I've been thinking and thinking on how to do this and can't come up with a working solution. Here is the link in the Google Playground. Any help would be greatly appreciated.
/*
File record.go
Author: Dan Huckson
Date: 20160120
Purpose: Number analyzer
*/
package main
import (
"fmt"
)
type Stats struct {
category map[string]Events
}
type Events struct {
event map[string]*Event
}
type Event struct {
value int64
}
func main() {
winners := [][]int{
{1, 2, 3, 4, 5, 6},
{2, 4, 6, 28, 26, 39},
{1, 4, 9, 10, 26, 39},
{1, 9, 19, 29, 26, 49},
{4, 5, 6, 28, 26, 49}}
keys := []string{"digits1", "digits2", "digits3", "digits4", "digits5", "digits6"}
stats := new(Stats)
stats.category = make(map[string]Events)
for _, key := range keys {
events, ok := stats.category[key]
if !ok {
events = *new(Events)
}
events.event = make(map[string]*Event)
stats.category[key] = events
}
fmt.Println()
for _, winner := range winners {
fmt.Println(winner)
stats.digits1("digits1", winner)
stats.digits2("digits2", winner)
stats.digits3("digits3", winner)
stats.digits4("digits4", winner)
stats.digits5("digits5", winner)
stats.digits6("digits6", winner)
}
}
func (stats *Stats) record(key string, balls string) {
event, ok := stats.category[key].event[balls]
if !ok {
event = new(Event)
stats.category[key].event[balls] = event
}
stats.category[key].event[balls].value += 1
word := ""
if len(balls) > 1 {
word = "Balls"
} else {
word = "Ball"
}
fmt.Printf("%s:%s\tCount:%d\n", word, balls_to_csv(balls), stats.category[key].event[balls].value)
}
func (stats *Stats) digits1(key string, winner []int) {
for i := 0; i < len(winner); i++ {
stats.record(key, string(winner[i]))
}
}
func (stats *Stats) digits2(key string, winner []int) {
for i := 0; i < len(winner)-1; i++ {
for j := i + 1; j < len(winner); j++ {
stats.record(key, string(winner[i])+string(winner[j]))
}
}
}
func (stats *Stats) digits3(key string, winner []int) {
for i := 0; i < len(winner)-2; i++ {
for j := i + 1; j < len(winner)-1; j++ {
for k := j + 1; k < len(winner); k++ {
stats.record(key, string(winner[i])+string(winner[j])+string(winner[k]))
}
}
}
}
func (stats *Stats) digits4(key string, winner []int) {
for i := 0; i < len(winner)-3; i++ {
for j := i + 1; j < len(winner)-2; j++ {
for k := j + 1; k < len(winner)-1; k++ {
for l := k + 1; l < len(winner); l++ {
stats.record(key, string(winner[i])+string(winner[j])+string(winner[k])+string(winner[l]))
}
}
}
}
}
func (stats *Stats) digits5(key string, winner []int) {
for i := 0; i < len(winner)-4; i++ {
for j := i + 1; j < len(winner)-3; j++ {
for k := j + 1; k < len(winner)-2; k++ {
for l := k + 1; l < len(winner)-1; l++ {
for m := l + 1; m < len(winner); m++ {
stats.record(key, string(winner[i])+string(winner[j])+string(winner[k])+string(winner[l])+string(winner[m]))
}
}
}
}
}
}
func (stats *Stats) digits6(key string, winner []int) {
for i := 0; i < len(winner)-5; i++ {
for j := i + 1; j < len(winner)-4; j++ {
for k := j + 1; k < len(winner)-3; k++ {
for l := k + 1; l < len(winner)-2; l++ {
for m := l + 1; m < len(winner)-1; m++ {
for n := m + 1; n < len(winner); n++ {
stats.record(key, string(winner[i])+string(winner[j])+string(winner[k])+string(winner[l])+string(winner[m])+string(winner[n]))
}
}
}
}
}
}
}
func balls_to_csv(key string) string {
s := ""
length := len(key)
for i := 0; i < length; i++ {
s += fmt.Sprintf("%d,", key[i])
}
return s[:len(s)-1]
}
As far as I can tell, you want to recursively find all the combinations of winning numbers. For example,
package main
import "fmt"
func combinations(n []int, c []int, ccc [][][]int) [][][]int {
if len(n) == 0 {
return ccc
}
if len(ccc) == 0 {
ccc = make([][][]int, len(n))
}
for i := range n {
cc := make([]int, len(c)+1)
copy(cc, c)
cc[len(cc)-1] = n[i]
ccc[len(cc)-1] = append(ccc[len(cc)-1], cc)
ccc = combinations(n[i+1:], cc, ccc)
}
return ccc
}
func main() {
n := []int{1, 2, 3, 4}
fmt.Println("winning numbers", n)
fmt.Println()
nw := 0
w := combinations(n, nil, nil)
fmt.Println("winning tickets:")
d := " digit : "
for i := range w {
fmt.Print(i+1, d)
d = " digits: "
for j := range w[i] {
nw++
fmt.Print(w[i][j], " ")
}
fmt.Println()
}
fmt.Println()
fmt.Println(nw, "winners")
}
Output:
winning numbers [1 2 3 4]
winning tickets:
1 digit : [1] [2] [3] [4]
2 digits: [1 2] [1 3] [1 4] [2 3] [2 4] [3 4]
3 digits: [1 2 3] [1 2 4] [1 3 4] [2 3 4]
4 digits: [1 2 3 4]
15 winners
Simplifying, you can see the recursion.
func combinations(n []int) {
if len(n) == 0 {
return
}
for i := range n {
combinations(n[i+1:])
}
return
}
The recursion terminates when len(n) == 0. In the for loop, i increases to len(n)-1, combinations(n[i+1:]) becomes combinations(n[len(n):]), and len(n[len(n):]) == 0, which will terminate the recursion.
Recursion is not a language specific concept. If you know what is recursion and if you know how to write a function in Go, then you can write a recursive function in Go.
This is a dummy recursive function in Go.
func f(n int) int {
if n < 0 {
return 0 // or something else
}
if n == 0 {
return 1
}
return n * f(n - 1)
}
This is a recursive function in Go, because,
It has a termination (base) condition(n <= 0)
f(n) depends on f(x) for all x < n.
It's written in Go.
I'm very new to Swift and I wanted to know how I'm supposed to modify an Int contained in my Int[]? I made it like I'd do it in Java but it, obviously, doesn't work: I get a Cannot assign to immutable value of type 'Int' compilation error.
Here is my code:
import Foundation
func createRandomArray(length: Int) -> [Int]{
var random = [Int]()
for index in 0...length{
random.append(Int(arc4random_uniform(100)))
}
return random
}
func insertionSort(toSort: [Int]) -> [Int]{
var length = toSort.count
for index in 1...length-1{
var key = toSort[index]
var previous = index-1
while(previous>0 && toSort[previous]>key){
// ERROR IS THERE
toSort[previous+1] = toSort[previous]
previous--
}
}
return toSort
}
var array = createRandomArray(10)
print(array)
print(insertionSort(array))
I thought that using a var instead of let will give a mutable object so that's why I'm a bit lost.
Thanks for help
EDIT:
I got this working answer yet, thanks to #vacawama:
import Foundation
func createRandomArray(length: Int) -> [Int]{
var random = [Int]()
for index in 0...length{
random.append(Int(arc4random_uniform(100)))
}
return random
}
func insertionSort(var toSort: [Int]) -> [Int]{
for firstIterator in 1...toSort.count-1{
var currentValue = toSort[firstIterator]
var previousPosition = firstIterator-1
while(previousPosition>=0 && toSort[previousPosition]>currentValue){
swap(&toSort[previousPosition+1], &toSort[previousPosition])
previousPosition--
}
}
return toSort
}
var array = createRandomArray(10)
print(array)
print(insertionSort(array))
Updated Answer for Swift 5.x and Beyond
Swift has had many changes in the 7 years since I answered this question. It is no longer valid to insert var into the function header to make an array modifiable. The modern way to do that is to make var toSort = toSort the first line of the function body.
Here is a modification of the OP's code with modern Swift updates:
func createRandomArray(_ length: Int) -> [Int] {
var random = [Int]()
for _ in 0..<length {
random.append(Int.random(in: 0..<100))
}
return random
}
func insertionSort(_ toSort: [Int]) -> [Int] {
var toSort = toSort
for firstIterator in 1..<toSort.count {
let currentValue = toSort[firstIterator]
var previousPosition = firstIterator - 1
while (previousPosition >= 0 && toSort[previousPosition] > currentValue) {
toSort.swapAt(previousPosition + 1, previousPosition)
previousPosition -= 1
}
}
return toSort
}
var array = createRandomArray(10)
print(array)
print(insertionSort(array))
A shorter version of createRandomArray:
func createRandomArray(_ length: Int) -> [Int] {
(0..<length).map { _ in .random(in: 0..<100) }
}
Note: Your insertionSort() will crash if it is passed an empty array. Add this guard statement to the start of the function body to prevent that:
guard !toSort.isEmpty else { return toSort }
Original Answer (now obsolete) for Swift 1.0
By default, array parameters are immutable within the called function. If you want to modify the copy of the array that is passed to insertionSort, add var before toSort in the function header.
func insertionSort(var toSort: [Int]) -> [Int]{
I played with the following using swift 3. Hope it'll help some people who come here.
import Cocoa
func ints(cnt: Int, ceiling: Int) -> [Int] {
var arr = [Int]()
for _ in 0 ..< cnt {
arr.append(Int(arc4random_uniform(UInt32(ceiling))))
}
return arr
}
func insertion(arr: inout [Int]) {
for i in 1..<arr.count {
var j = i
let x = arr[i]
while j > 0 && arr[j - 1] > x {
arr[j] = arr[j - 1]
j -= 1
}
arr[j] = x
}
}
let a = ints(cnt: 10, ceiling: 100)
print(a)
var b = a
insertion(arr: &b)
print(b)
output:
[13, 30, 68, 19, 1, 4, 28, 65, 96, 13]
[1, 4, 13, 13, 19, 28, 30, 65, 68, 96]
For comparison, here is an implementaion in java:
void insertionSort(int[] arr) {
for(int i = 1; i < arr.length; i++) {
int x = arr[i];
int j = i;
while(j > 0 && arr[j - 1] > x) {
arr[j] = arr[j - 1];
j--;
}
arr[j] = x;
}
}
struct InsertionSort {
static func sort(data: Array<Int> = [5,9,1,8,2,4,3,1]) {
var data = data
for (i, e) in data.enumerated() where i > 0 && e < data[i - 1] {
traverseBackwardAndSwap(i, &data)
}
printData(data)
}
private static func traverseBackwardAndSwap(_ i: Int, _ data: inout [Int]) {
for i in (0...i).reversed() where i > 0 && data[i] < data[i-1] {
let temp = data[i]
data[i] = data[i-1]
data[i-1] = temp
}
}
private static func printData(_ data: [Int]) {
for e in data {
print("\(e)")
}
}
}
Swift 5: Generic Insertion sort
func insertionSort<U: Comparable>(with array: inout [U]) -> [U] {
for i in 1..<array.count {
let temp = array[i]
var insertionIndex = i
for j in (0...i).reversed() where j>0 && temp < array[j-1] {
array[j] = array[j-1]
insertionIndex = j-1
}
array[insertionIndex] = temp
}
return array
}
Input:-
var intArray = [8, 3, 5, 10, 4, -1, 17, 3, 18, 10]
var floatArray = [12.231, 12.23, 14.5, 3.4, 67.899, 0.0, -1.234]
var doubleArray = [123.43555, 123.1223332, -121.2212, 23.343434, 1.232434]
var stringArray = ["Ratheesh", "Srini", "Thangu", "Muthu", "Gopi"]
print(insertionSort(with: &intArray))
print(insertionSort(with: &floatArray))
print(insertionSort(with: &doubleArray))
print(insertionSort(with: &stringArray))
Output:-
[-1, 3, 3, 4, 5, 8, 10, 10, 17, 18]
[-1.234, 0.0, 3.4, 12.23, 12.231, 14.5, 67.899]
[-121.2212, 1.232434, 23.343434, 123.1223332, 123.43555]
["Gopi", "Muthu", "Ratheesh", "Srini", "Thangu"]