小小祝贺自己多年前的java代码写入C库
aide吧
全部回复
仅看楼主
level 12
0_666 楼主
自己五年前写的语音计算器,由于那时的aide只有2.2.6版本不支持c/c++,后来版本更新能支持,只是迫于生活所逼,放下几年没玩aide,最近几个月重新玩了起来,首先想到的是把它的语音编码部分写入c库。
2018年01月12日 02点01分 1
level 12
0_666 楼主
说起来容易做起来难,几年没沾代码边了,以前学过的东西都忘记了,只好重新复习,前后一个多月复习了c、c++、android后,才能看懂自己以前写的代码。
2018年01月12日 02点01分 2
level 12
0_666 楼主
那个2013年写的计算器,记得当时学习安卓还不到一年,每天只知道看书不知道动手写东西,后来本吧的某一位大神提倡初学者从计算器开始练习,于是我就动手写了一个最简单的 1+1=2 的东西,后来一看这个也太简单了而且也没有什么用,于是乎就不断的改进,先添加振动,后添加按键语音、起动音乐、换肤、透明色等等,最后在长达一年多经过上千次的试验下,成功添加了智能语音。
2018年01月12日 03点01分 3
level 12
0_666 楼主
当时的所有代码都是用java写的,语音读数部分要处理个、十、百、千、万、亿的所有单位,还要自动判断数字0,非法字符,数组越界等等,这样一来,一个看起来不起眼的小应用,java代码就有三千多行。
2018年01月12日 03点01分 4
level 12
0_666 楼主
后来仔细推敲觉得有些留肿,有必要加工提炼,反复提纯后代码减少到一千多行,而智能语音部分就有几百行,是不是还能精减呢?但是再试着减少代码就会出现功能缺少的现象,
2018年01月12日 03点01分 5
level 12
0_666 楼主
于是想着把代码最多的部分换一种语言来写,看能不能再减小,说干就干,连忙下载 4455jkjh1大神的最新版 aide 和 ndk,用C++ 重写智能语音部分。
2018年01月12日 03点01分 6
level 12
0_666 楼主
不试不知道,一试大有收获,几百行的 java 智能语音代码就变为只有五、六十行的C++代码了,仔细分析代码能减小的原因是 C++ 有指针功能,处理数组特别方便
2018年01月12日 03点01分 7
level 12
0_666 楼主
有人说 C 库会拖慢 apk 的运行速度,也有人说 C 代码的运行速度更快,到底怎么样本人也不知道,但是可以肯定的是:汇编代码执行效率是至高无尚的,不过编写效率就低了,当时也想到用汇编写执行效率高,但是刚写的时候,看到一个遍历数组的代码就要十几行,要实行整个功能,代码要达到几千行,想想还是放弃了
2018年01月12日 04点01分 8
level 12
0_666 楼主
这是C代码:
include <string.h>
#include <jni.h>
extern "C"
{
JNIEXPORT jstring JNICALL Java_com_mycompany_myndkapp_HelloJni_stringFromJNI(JNIEnv* env, jobject thiz,jstring jstr)
{
const char*chr=env->GetStringUTFChars(jstr,NULL);
char src[20]={0};
strcpy(src,chr);
int lensrc = strlen(src);
if(lensrc <= 17 & lensrc != 0)
{
char*p = NULL;
p=src;
char out[30] = {0};
int i = 0;// i是循环变量
int j = 0;// j是输出字符数组的单位标记
while (*p != '\0' && *p != '.')//整数
{
if( *p != '0' ){ out[j] = *p; j++;} //每位1~9的数字放入输出字符数组。
if (*p !='0' &&u *p != '-')
{
if (i == lensrc - 2 || i == lensrc - 6 || i == lensrc - 10){ out[j]='S'; j++; }//十
if (i == lensrc - 3 || i == lensrc - 7 || i == lensrc - 11){ out[j]='B'; j++; }//百
if (i == lensrc - 4 || i == lensrc - 8 || i == lensrc - 12){ out[j]='Q'; j++; } //千
} // k++防止先写入的字符被后写入的字符覆盖。
if (i == lensrc - 5 && *p !='-' && lensrc < 9 ){out[j]='W'; j++; }//无亿位的万位
if (i == lensrc - 5 && lensrc >= 9)
{
if (*p !='0'|| *(p-1) !='0' || *(p-2) !='0' || *(p-3) !='0'){ out[j]='W';j++; }//有亿位需判零的万位
}
if (i == lensrc - 9 && *p !='0'){ out[j]='Y'; j++; }//亿
if (i != lensrc - 1 )//数字零处理
{
if ( *p =='0' && *(p+1) !='0')
{ out[j]='0'; j++; }
}
i++;
p++;
}
env->ReleaseStringUTFChars(jstr,chr);//释放指向jstr的chr指针。
return env->NewStringUTF(out);
} else
{
env->ReleaseStringUTFChars(jstr,chr);
return env->NewStringUTF("0");
}
}
}
2018年01月12日 04点01分 9
level 12
0_666 楼主
java的有这五倍代码多,上面是整数部分,还有比这少的小数部分处理代码。
2018年01月12日 04点01分 10
不是小数,是浮点
2018年01月13日 11点01分
level 12
0_666 楼主
写好编译后进行调试,通过textView显示c库输出的处理结果,给c库传入一个由数字 0〜9、正负号和小数点组成的字符串,c 库立即输出带单位的预期结果,非常满意,但是在正式播放语音时却无声,为这个问题搞了半天,后来才搞明白,原来c库输出的字符串拆分为单个字符时,只能用char类型,不能用String类型,当拆成char类型后完美解决。
2018年01月12日 05点01分 11
level 12
0_666 楼主
c库还具有超强的容错功能,能过滤非法字符,例如输入一个含有两个小数点的double数,它会以第一个小数作为小数的依据,并去掉第二个小数点,输入中间夹有其它符号的double数,它会只取出0〜9的数字来处理。
2018年01月12日 05点01分 12
level 12
0_666 楼主
只看书学习远远是不够的,要多动手多用脑才行,当你动手创作一个东西时,虽然是费时费力费精神,但是收获是不少的,实践才是检验真理的唯一标准。
2018年01月12日 05点01分 13
level 10
膜拜一下大神
2018年01月12日 05点01分 14
level 12
膜拜膜拜
2018年01月12日 07点01分 15
1 2 尾页