如何添加两个数组以产生第三个数组?

时间:2019-05-19 23:51:45

标签: c arrays

这是我的代码:

didTapConvertButton(_:)

我希望输出应为:

JSONDecoder

但是实际结果是:

//  CurrencyViewController.swift

import UIKit
import Alamofire

// types used by this view controller

struct Currency {
    let code: String              // standard three character code
    let localeIdentifier: String  // a `Locale` identifier string used to determine how to format the results
}

enum CurrencyExchangeError: Error {
    case currencyNotSupplied
    case valueNotSupplied
    case currencyNotFound
    case webServiceError(String)
    case unknownNetworkError(Data?, HTTPURLResponse?)
}

struct ExchangeRateResponse: Codable {
    let error: String?
    let base: String?
    let rates: [String: Double]?
}

class CurrencyExchangeViewController: UIViewController {

    // outlets

    @IBOutlet weak var inputTextField: UITextField!
    @IBOutlet weak var inputCurrencySegmentedControl: UISegmentedControl!
    @IBOutlet weak var outputCurrencySegmentedControl: UISegmentedControl!
    @IBOutlet weak var resultLabel: UILabel!

    // private properties

    private let currencies = [
        Currency(code: "EUR", localeIdentifier: "fr_FR"),
        Currency(code: "JPY", localeIdentifier: "jp_JP"),
        Currency(code: "CNY", localeIdentifier: "ch_CH"),
        Currency(code: "USD", localeIdentifier: "en_US")
    ]

    override func viewDidLoad() {
        super.viewDidLoad()
        navigationController?.isNavigationBarHidden = true
        updateCurrencyControls()
    }

    @IBAction func didTapConvertButton(_ sender: Any) {
        let inputIndex = inputCurrencySegmentedControl.selectedSegmentIndex
        let outputIndex = outputCurrencySegmentedControl.selectedSegmentIndex

        guard inputIndex >= 0, outputIndex >= 0 else {
            resultLabel.text = errorMessage(for: CurrencyExchangeError.currencyNotSupplied)
            return
        }

        guard let text = inputTextField.text, let value = Double(text) else {
            resultLabel.text = errorMessage(for: CurrencyExchangeError.valueNotSupplied)
            return
        }

        performConversion(from: inputIndex, to: outputIndex, of: value) { result in
            switch result {
            case .failure(let error):
                self.resultLabel.text = self.errorMessage(for: error)

            case .success(let string):
                self.resultLabel.text = string
            }
        }
    }

    func updateCurrencyControls() {
        outputCurrencySegmentedControl.removeAllSegments()
        inputCurrencySegmentedControl.removeAllSegments()

        enumerateCurrencies { index, code in
            outputCurrencySegmentedControl.insertSegment(withTitle: code, at: index, animated: false)
            inputCurrencySegmentedControl.insertSegment(withTitle: code, at: index, animated: false)
        }
    }
}

// these might better belong in a presenter or view model rather than the view controller

private extension CurrencyExchangeViewController {

    func enumerateCurrencies(block: (Int, String) -> Void) {
        for (index, currency) in currencies.enumerated() {
            block(index, currency.code)
        }
    }

    func errorMessage(for error: Error) -> String {
        switch error {
        case CurrencyExchangeError.currencyNotFound:
            return NSLocalizedString("No exchange rate found for those currencies.", comment: "Error")

        case CurrencyExchangeError.unknownNetworkError:
            return NSLocalizedString("Unknown error occurred.", comment: "Error")

        case CurrencyExchangeError.currencyNotSupplied:
            return NSLocalizedString("You must indicate the desired currencies.", comment: "Error")

        case CurrencyExchangeError.valueNotSupplied:
            return NSLocalizedString("No value to convert has been supplied.", comment: "Error")

        case CurrencyExchangeError.webServiceError(let message):
            return NSLocalizedString(message, comment: "Error")

        case let error as NSError where error.domain == NSURLErrorDomain:
            return NSLocalizedString("There was a network error.", comment: "Error")

        case is DecodingError:
            return NSLocalizedString("There was a problem parsing the server response.", comment: "Error")

        default:
            return error.localizedDescription
        }
    }

    func performConversion(from fromIndex: Int, to toIndex: Int, of value: Double, completion: @escaping (Result<String?>) -> Void) {
        let originalCurrency = currencies[fromIndex]
        let outputCurrency = currencies[toIndex]

        fetchExchangeRates(for: originalCurrency.code) { result in
            switch result {
            case .failure(let error):
                completion(.failure(error))

            case .success(let exchangeRates):
                guard let exchangeRate = exchangeRates.rates?[outputCurrency.code] else {
                    completion(.failure(CurrencyExchangeError.currencyNotFound))
                    return
                }

                let outputValue = value * exchangeRate

                let locale = Locale(identifier: outputCurrency.localeIdentifier)
                let string = formatter(for: locale).string(for: outputValue)
                completion(.success(string))
            }
        }

        /// Currency formatter for specified locale.
        ///
        /// Note, this formats number using the current locale (e.g. still uses
        /// your local grouping and decimal separator), but gets the appropriate
        /// properties for the target locale's currency, namely:
        ///
        ///  - the currency symbol, and
        ///  - the number of decimal places.
        ///
        /// - Parameter locale: The `Locale` from which we'll use to get the currency-specific properties.
        /// - Returns: A `NumberFormatter` that melds the current device's number formatting and
        ///            the specified locale's currency formatting.

        func formatter(for locale: Locale) -> NumberFormatter {
            let currencyFormatter = NumberFormatter()
            currencyFormatter.numberStyle = .currency
            currencyFormatter.locale = locale

            let formatter = NumberFormatter()
            formatter.numberStyle = .currency
            formatter.currencyCode = currencyFormatter.currencyCode
            formatter.currencySymbol = currencyFormatter.currencySymbol
            formatter.internationalCurrencySymbol = currencyFormatter.internationalCurrencySymbol
            formatter.maximumFractionDigits = currencyFormatter.maximumFractionDigits
            formatter.minimumFractionDigits = currencyFormatter.minimumFractionDigits
            return formatter
        }
    }
}

// this might better belong in a network service rather than in the view controller

private extension CurrencyExchangeViewController {
    func fetchExchangeRates(for inputCurrencyCode: String, completion: @escaping (Result<ExchangeRateResponse>) -> Void) {
        Alamofire.request("https://api.exchangeratesapi.io/latest?base=\(inputCurrencyCode)").response { response in
            guard response.error == nil, let data = response.data else {
                completion(.failure(response.error ?? CurrencyExchangeError.unknownNetworkError(response.data, response.response)))
                return
            }

            do {
                let exchangeRates = try JSONDecoder().decode(ExchangeRateResponse.self, from: data)
                if let error = exchangeRates.error {
                    completion(.failure(CurrencyExchangeError.webServiceError(error)))
                } else {
                    completion(.success(exchangeRates))
                }
            } catch {
                completion(.failure(error))
            }
        }
    }
}

3 个答案:

答案 0 :(得分:1)

我认为您之前输入的“预期输出”是错误的(我认为应该是186 240 294 348 402 456 510 564 618 672),并且您有不必要的循环和额外的索引变量。再检查一遍。这是我认为您想做的事情的方法:

int main() {

    int integer1[10], integer2[10], integertotal[10];
    int i;    
    for (i = 0; i < 10; i++) {
        integer1[i] = 2 * (i + 4);
        printf("    %d", integer1[i]);
    }
    printf("\n");

    for (i = 0; i < 10; i++) {
        integer2[i] = 3 * (i + 3);
        printf("    %d", integer2[i]);
    }
    printf("\n");

    for (i = 0; i < 10; i++) {
        integertotal[i] = integer1[i] * 12 + integer2[i] * 10;
        printf("   %d", integertotal[i]);
    }
    printf("\n");

    for (i = 0; i < 10; i++)
        printf("%d %d+%d=%d\n", i, integer1[i], integer2[i], integertotal[i]);  //I don't understand the output you want. 8+9=186? Why?
    printf("\n");

    return 0;
}

答案 1 :(得分:0)

在第三个循环中,将i和j用作integer1和integer2的索引,因此您尝试访问这两个数组中不存在的11个项目。所以我认为您的代码应该是这样的。

#include <stdio.h>

int main()
{
    int integer1[10], integer2[10], integertotal[10];
    int i, j, index;

    for (i = 0; i < 10; i++)
        integer1[i] = 2 * (i + 4);
    for (i = 0; i < 10; i++)
        printf("    %d", integer1[i]);

    printf("\n");

    for (j = 0; j < 10; j++)
        integer2[j] = 3 * (j + 3);
    for (j = 0; j < 10; j++)
        printf("    %d", integer2[j]);

    printf("\n");

    for (index = 0; index < 10; index++)
        integertotal[index] = integer1[index] * 12 + integer2[index] * 10;
    for (index = 0; index < 10; index++)
        printf("   %d", integertotal[index]);

    printf("\n\n");

    for (index = 0; index < 10; index++)
        printf("%d %d+%d=%d\n", index, integer1[index], integer2[index], integertotal[index]);
}

答案 2 :(得分:0)

  

如何添加两个数组以产生第三个数组?

我们可以编写这样的函数

void sum_arrays(size_t n, int *src_1, int *src_2, int *dest)
{
    for (size_t i = 0; i < n; ++i)
    {
        // Note that 'i' is local, initialized and it is used for all the arrays
        dest[i] = src_1[i] + src_2[i];
    }
}

这当然不会产生OP期望的输出,但是感谢Bishal Jaiswal,他显然是对“正确”公式进行了反向工程,我们可以使用它

void calc_array(size_t n, int *src_1, int *src_2, int *dest)
{
    for (size_t i = 0; i < n; ++i)
    {
        dest[i] = (src_1[i] * 12 + src_2[i] * 10 + (i + 1)) * 2;
        //              ^^^             ^^^         ^^^^^
    } 
}

可测试的HERE

在问询者发布的代码中,除了使用错误的公式外,数组还使用错误的变量进行了索引

int integer1[10], integer2[10], integertotal[10];
int i, j, index;  // <---

for (i = 0; i < 10; i++)
// ...
for (j = 0; j < 10; j++)
// ...
// Now both 'i' and 'j' are equal to 10
// ...
for (index = 0; index < 10; index++)
    integertotal[index] = integer1[i] * 12 + integer2[j] * 10;
// Those are out of bounds now    ^^^                ^^^                
// ...
// Same later
for (index = 0; index < 10; index++)
    printf("%d %d+%d=%d\n", index, integer1[i], integer2[j], integertotal[index]);
//                                         ^^^          ^^^