【问题标题】:Need help translating java program to C需要帮助将 java 程序翻译成 C
【发布时间】:2015-04-28 11:00:35
【问题描述】:

这个程序对非常大的数字进行除法(我只需要最多 1000 位数字)。因为没有数据类型可以处理非常大的数字,所以我们使用数组。 我正在尝试将这个 Java 程序翻译成 C。我已经完成了一些,但是在将字符串转换为 C 兼容的数据类型时遇到了麻烦。请记住,我们需要将数字作为字符串然后转换为 int。

最大的挑战似乎是 String、StringBuilder 和 append。我不知道如何翻译这些。

最麻烦的是:

if (len1 < len2) return new String[]{"0", n1};
          StringBuilder digits = new StringBuilder();
          String n3 = n1.substring(0, len2);

Java 代码:

import java.io.*;
import java.util.*;


class BigDiv
{
   public static void main(String[] args)
   {
      String n1 = "30";
      String n2 = "2";
      String[] results = Divide(n1, n2);
      System.out.println("Quotient is  : " + results[0]);
      System.out.println("Remainder is : " + results[1]);
   }

   static String[] Divide(String n1, String n2)
   {
      Boolean negative = false;
      if (n1.charAt(0) == '-' ^ n2.charAt(0) == '-') negative = true;
      if (n1.charAt(0) == '-') n1 = n1.substring(1);
      if (n2.charAt(0) == '-') n2 = n2.substring(1);
      if (n1.equals("0") && n2.equals("0"))
      {
         return new String[] {"Not a number", "0"};
      }

      if (n2.equals("0"))
      {
         if (!negative) return new String[] {"Infinity", "0"};
         return new String[] {"-Infinity", "0"};
      }

      int len1 = n1.length();
      int len2 = n2.length();
      if (len1 < len2) return new String[]{"0", n1};
      StringBuilder digits = new StringBuilder();
      String n3 = n1.substring(0, len2);
      int len3 = len2;
      String n4;
      int quotient; 
      int index = len2 - 1;

      while(true)
      {
         quotient = 0;

         while(true)
         {
            n4 = Subtract(n3, n2);  

            if (n4 == "-1") 
            {
               break;
            } 

            quotient++;

            //System.out.println(quotient);

            if (n4 == "0")
            { 
               n3 = "0";
               break;
            }

            n3 = n4;
         }

         if (digits.toString().equals("0"))
         {
             digits.setCharAt(0, (char)(quotient + 48));
         } 
         else
         {
             digits.append((char)(quotient + 48));   
         }

         if (index < len1 - 1)
         { 
            index++;
            if (n3.equals("0")) n3 = "";
            n3 += n1.charAt(index);
            len3 = n3.length();
         }
         else
         {
            String result = new String(digits); 
            if (negative)
            {
               if (!result.equals("0")) result = "-" + result;
               if (!n3.equals("0")) n3 = "-" + n3;
            }
            return new String[]{result, n3}; 

         }                        
      }   
   }          

   static String Subtract(String n1, String n2)
   {
      int len1 = n1.length();
      int len2 = n2.length(); 
      if (len1 < len2) return "-1";
      int max = Math.max(len1, len2);
      int[] ia1 = new int[max];
      int[] ia2 = new int[max];
      int[] ia3 = new int[max];
      for(int i = max - len1; i < max; i++) ia1[i] = n1.charAt(i + len1 - max) - 48;
      for(int i = max - len2; i < max; i++) ia2[i] = n2.charAt(i + len2 - max) - 48;
      int diff = 0;
      int carry = 0;


      for(int i = max - 1; i >= 0; i--)
      {
         diff = ia1[i] - ia2[i] - carry;
         carry = 0;
         if (diff < 0)
         {
            diff += 10;
            carry = 1;
         } 
         ia3[i] = diff;
      }

      if (carry == 1) return "-1";

      // find first non-zero element of array ia3
      int first = -1;
      for (int i = 0; i < max; i++)
      {
         if (ia3[i] != 0)
         {
            first = i;
            break;
         }
      }

      if (first == -1) first = max - 1;
      char[] c3 = new char[max - first];
      for(int i = first; i < max; i++) c3[i - first] = (char)(ia3[i] + 48);
      //System.out.println("c IS : " + c3[0]);
      return new String(c3);       
   }

到目前为止我的 C 代码:(在除法函数中,有一个我不需要的 NaN 和负数检查。我也不应该使用 VLA。)

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

    int Divide(char n1[], char n2[]);
    int Subtract(char n1[], char n2[]);

    int main()
    {
      char n1[] = "30";
      char n2[] = "2";
      char results[] = Divide(n1, n2);
      printf("Quotient is  : %d", results[0]);
      printf("Remainder is : %d", results[1]);
    }

    int Divide(char n1[], char n2[])
    {
      /*Boolean negative = false;
      if (n1[0] == '-' ^ n2[0] == '-') negative = true;
      if (n1[0] == '-') n1 = n1.substring(1);
      if (n2[0] == '-') n2 = n2.substring(1);
      if (n1.equals("0") && n2.equals("0"))
      {
         return new String[] {"Not a number", "0"};
      }

      if (n2.equals("0"))
      {
         if (!negative) return new String[] {"Infinity", "0"};
         return new String[] {"-Infinity", "0"};
      }*/

      int len1 = strlen(n1);
      int len2 = strlen(n2);
      if (len1 < len2) return new String[]{"0", n1};
      StringBuilder digits = new StringBuilder();
      String n3 = n1.substring(0, len2);
      int len3 = len2;
      String n4;
      int quotient;
      int index = len2 - 1;

      while(true)
      {
         quotient = 0;

         while(true)
         {
            n4 = Subtract(n3, n2);

            if (n4 == "-1")
            {
               break;
            }

            quotient++;

            if (n4 == "0")
            {
               n3 = "0";
               break;
            }

            n3 = n4;
         }

         if (digits.toString().equals("0"))
         {
             digits.setCharAt(0, (char)(quotient + 48));
         }
         else
         {
             digits.append((char)(quotient + 48));
         }

         if (index < len1 - 1)
         {
            index++;
            if (n3.equals("0")) n3 = "";
            n3 += n1[index];
            len3 = n3.length();
         }
         else
         {
            String result = new String(digits);
            if (negative)
            {
               if (!result.equals("0")) result = "-" + result;
               if (!n3.equals("0")) n3 = "-" + n3;
            }
            return new String[]{result, n3};

         }
      }
    }

    int Subtract(char n1[], char n2[])
    {
      int len1 = n1.length();
      int len2 = n2.length();
      if (len1 < len2) return "-1";
      int max;

      if(len1>len2) max = len1;
      else if(len2>len1) max = len2;
      else max = len1;

      int ia1[max];
      int ia2[max];
      int ia3[max];
      for(int i = max - len1; i < max; i++) ia1[i] = n1[i + len1 - max] - 48;
      for(int i = max - len2; i < max; i++) ia2[i] = n2[i + len2 - max] - 48;
      int diff = 0;
      int carry = 0;


      for(int i = max - 1; i >= 0; i--)
      {
         diff = ia1[i] - ia2[i] - carry;
         carry = 0;
         if (diff < 0)
         {
            diff += 10;
            carry = 1;
         }
         ia3[i] = diff;
      }

      if (carry == 1) return "-1";

      // find first non-zero element of array ia3
      int first = -1;
      for (int i = 0; i < max; i++)
      {
         if (ia3[i] != 0)
         {
            first = i;
            break;
         }
      }

      if (first == -1) first = max - 1;
      char c3[max - first];
      for(int i = first; i < max; i++) c3[i - first] = (char)(ia3[i] + 48);
      return new String(c3);
    }

【问题讨论】:

  • 不要那样做,往那个方向翻译一个程序是不行的,因为编程语言太不一样了,我建议重写程序,使用适合该语言的设计。
  • StringBuilder 和 append 也返回
  • 除了实际学习 C,good reference 可能会变得很方便。
  • @vvvsg 你说你知道 C,但是,对不起,你知道 return new String[]{result, n3};
  • @vvvsg 你必须形象地翻译你的程序,而不是字面。如果它对您有帮助,请用简单的英语一步一步地写下您的 Java 程序的功能。然后隐藏你的java代码,按照你刚才写的文字用C实现同样的程序。

标签: java c


【解决方案1】:

C 中的字符串只是由 0 值字节终止的字符序列。没有专用的字符串类型;它们存储为char 的数组,并且没有为数组定义诸如=+== 之类的运算符。

要分配字符串,请使用strcpy 库函数。要将字符串相互附加,请使用 strcat 库函数。要比较字符串,请使用strcmp

您必须自己进行内存管理;当您扩展字符串时,C 不会自动分配更多内存,当没有更多对该内存的引用时,它也不会进行任何自动垃圾回收,这意味着您必须显式释放任何动态分配的内存。使用malloccalloc 分配内存,realloc 分配或扩展已使用malloccallocrealloc 分配的缓冲区,并使用free 释放使用@ 分配的内存987654342@、callocrealloc

malloc 不初始化动态分配的内存; calloc 会将其初始化为全位 0。

这里有一些示例 C 代码,它们将分配、分配、追加、比较和解除分配字符串:

#include <stdlib.h>
#include <string.h>
#include <stdio.h>

#define INITIAL_SIZE 20

int main( void )
{
  /**
   * Allocate space to store a string; the +1 is to make sure
   * we have space for the 0 terminator.
   */
  char *str1 = calloc( INITIAL_SIZE+1, sizeof *str1 ); 
  size_t str1size = INITIAL_SIZE + 1;

  /**
   * str2 will point to a string literal; literals are stored as
   * arrays of char such that they are allocated at program startup
   * and held until the program terminates.  String literals may
   * not be modified, so we're declaring the pointer as const char *.
   */
  const char *str2 = " of the Emergency Broadcast System";

  /**
   * Copy a string to that buffer
   */
  strcpy( str1, "This is a test" );

  /**
   * Extend the buffer to hold more stuff; typical strategy is
   * to double the buffer size each time.  For this particular
   * example this loop should only run once.  
   */
  while ( strlen( str1 ) + strlen( str2 ) > str1size)
  {
    char *tmp = realloc( str1, 2 * str1size );
    if ( !tmp )
    {
       // realloc failed, for this example we treat it as a fatal error
       exit( -1 );
    }
    str1 = tmp;
    str1size *= 2;
  }

  /**
   * Append to the buffer
   */
  strcat( str1, str2 );

  // do something interesting with str1 here

  /**
   * Deallocate the buffer
   */
  free( str1 );

  return 0;
}

必须确保您的目标缓冲区足够大以容纳您正在写入的任何内容。 C 不对数组访问进行边界检查,如果您尝试在数组边界之外读取或写入,它也不会抛出异常(除非您尝试访问受保护的内存,但这是系统异常,而不是语言例外)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多