паника: ошибка во время выполнения: неверный адрес памяти или разыменование нулевого указателя [сигнал 0xc0000005 код = 0x0 адрес = 0x8 pc = 0x48be5c] маршрут 1 [выполняется]: - PullRequest
0 голосов
/ 22 ноября 2018

Я пытаюсь реализовать добавление полиномов, используя связанный список.Программа успешно добавляет коэффициенты степени 0, но после первого обхода паникует.Вот код, который я написал до сих пор.после инициализации temp1! = nil цикл повторяется по другому, но не запускается, если цикл при разных мощностях переходит в состояние паники

package main

import (
    "fmt"
)

type Node struct {
    coefficient int
    power       int
    next        *Node
}

type list struct {
    head  *Node
    count int
}

func main() {
    list1 := &list{}
    list1.addVariable(5, 2)
    list1.addVariable(4, 1)
    list1.addVariable(3, 0)
    list1.print()
    list2 := &list{}
    list2.addVariable(4, 1)
    list2.addVariable(2, 0)
    list2.print()
    list4 := addLists(list1, list2)
    list4.print()

}

func (lst *list) print() {
    temp := lst.head
    for temp != nil {
        fmt.Print(temp.coefficient, "x", "^", temp.power, "+")
        temp = temp.next
    }
    fmt.Println("\n")
}

func (lst *list) addVariable(coefficient int, power int) {
    lst.head = &Node{coefficient, power, lst.head}
    lst.count++
}

func addLists(list1 *list, list2 *list) *list {
    list3 := &list{}
    temp1 := list1.head
    temp2 := list2.head
    fmt.Println("reached") // for debugging purposes
    if list1.count > list2.count {
        fmt.Println("\nreached 2") // for debugging purposes
        for temp1 != nil {
            fmt.Println("reached3") // for debugging purposes
            if temp1.power != temp2.power {
                fmt.Println("reached4") // for debugging purposes
                list3.normalAdd(temp1, temp2)
                temp1 = temp1.next

            } else {
                fmt.Println("reached5") // for debugging purposes
                node4 := add(temp1, temp2)
                list3.exlusiveAdd(node4)
                temp1 = temp1.next
                temp2 = temp2.next
            }
        }
    }
    return list3
}

func (lst *list) normalAdd(node6 *Node, node7 *Node) {
    node6.next = lst.head
    lst.head = node6
    node7.next = lst.head
    lst.head = node7
    lst.count += 2
}

func (lst *list) exlusiveAdd(node5 *Node) {
    node5.next = lst.head
    lst.head = node5
    lst.count++
}

func add(node1, node2 *Node) *Node {
    node3 := &Node{}
    node3.coefficient = node1.coefficient + node2.coefficient
    node3.power = node1.power
    return node3
}

Вывод при запуске программы:

3x^0+4x^1+5x^2+
2x^0+4x^1+
reached

reached 2
reached3
reached5
reached3
reached5
reached3
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0xffffffff addr=0x0 pc=0xd48e6]

goroutine 1 [running]:
main.addLists(0x41c7a8, 0x41c7a0, 0x40c120, 0x1d)
    /tmp/sandbox520212269/main.go:56 +0x186
main.main()
    /tmp/sandbox520212269/main.go:28 +0x220

детская площадка здесь

Обновление: Спасибо за решение, но я успешно написал код для вышеуказанной проблемы.вот.основной пакет

import (
"fmt"
)

type Node struct {
coefficient int
power       int
next        *Node
}

type list struct {
head  *Node
count int
}

func main() {
list1 := &list{}
list1.addVariable(5, 2)
list1.addVariable(4, 1)
list1.addVariable(3, 0)
list1.print()
list2 := &list{}
list2.addVariable(4, 1)
list2.addVariable(2, 0)
list2.print()
poly := addPoly(list1, list2)
poly.print()
}

func (lst *list) print() {
temp := lst.head
for temp != nil {
    fmt.Print(temp.coefficient, "x", "^", temp.power, "+")
    temp = temp.next
}
fmt.Println("\n")
}

func (lst *list) addVariable(coefficient int, power int) {
lst.head = &Node{coefficient, power, lst.head}
lst.count++
}

func addPoly(list_1 *list, list_2 *list) *list {
list_3 := &list{}
temp_1 := list_1.head
temp_2 := list_2.head
if list_1.count > list_2.count {
    for temp_1 != nil && temp_2 != nil {
        if temp_1.power == temp_2.power {
            new_coefficient := temp_1.coefficient + temp_2.coefficient
            new_power := temp_1.power
            list_3.addVariable(new_coefficient, new_power)
            temp_1 = temp_1.next
            temp_2 = temp_2.next
        } else if temp_1.power != temp_2.power {
            list_3.addVariable(temp_1.coefficient, temp_1.power)
            list_3.addVariable(temp_2.coefficient, temp_2.power)
            temp_1 = temp_1.next
            temp_2 = temp_2.next
        }
    }
}
for temp_1 != nil {
    list_3.addVariable(temp_1.coefficient, temp_1.power)
    temp_1 = temp_1.next
}
return list_3
}

Ответы [ 2 ]

0 голосов
/ 22 ноября 2018

В вашем коде много ошибок, как и в первом опубликованном ответе.Кроме того, почему необходимо отслеживать количество терминов?Я бы посоветовал вам воспользоваться более простым подходом.

type Node struct {
    Coeff int
    Power int
    next  *Node
}

// Add coeff^power to a polynomial
func (n *Node) AddTerm(coeff int, power int) {
    for t := n; t != nil; t = t.next {
        if t.Power == power {
            t.Coeff += coeff
            return
        }
    }

    n.next = &Node{coeff, power, n.next}
}

// Add a polynomial m to the polynomial
func (n *Node) AddPolynomial(m *Node) {
    for t := m; t != nil; t = t.next {
        n.AddTerm(t.Coeff, t.Power)
    }
}

// The string representation of the polynomial
func (n *Node) String() string {
    buff := strings.Builder{}
    for t := n; t != nil; t = t.next {
        fmt.Fprintf(&buff, " + %d^%d", t.Coeff, t.Power)
    }
    return buff.String()[3:]
}

// Add two polynomials together creating a new one
func Add(a *Node, b *Node) *Node {
    c := &Node{}
    c.AddPolynomial(a)
    c.AddPolynomial(b)
    return c
}

func main() {

    p1 := &Node{}

    p1.AddTerm(5, 2)
    p1.AddTerm(4, 1)
    p1.AddTerm(3, 0)

    fmt.Println(p1)

    p2 := &Node{}

    p2.AddTerm(4, 1)
    p2.AddTerm(2, 0)

    fmt.Println(p2)

    p3 := Add(p1, p2)

    fmt.Println(p3)
}

Детская площадка

0 голосов
/ 22 ноября 2018

Ошибка возникла из-за того, что вы пытались получить доступ к свойству .power из объекта nil в приведенном ниже коде.И temp1, и temp2 являются nil.

if temp1.power != temp2.power {
   // ...
}

Свойство .head в структуре list имеет тип данных указателя.Нулевое значение типа данных указателя nil.В вашем коде list1 и list2 имеют значение nil в свойстве .head.

Что вам нужно сделать: явно инициализировать значение свойства .head при создании list1 и list2.Тогда ошибка паники исчезнет и ваш код будет работать правильно.

list1 := &list{head: new(Node)}
// ...
list2 := &list{head: new(Node)}
// ...

Детская площадка: https://play.golang.org/p/vPK3pYKht3E

...